Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make authentication linker friendly #24708

Merged
merged 3 commits into from
Aug 10, 2020
Merged

Make authentication linker friendly #24708

merged 3 commits into from
Aug 10, 2020

Conversation

davidfowl
Copy link
Member

@davidfowl davidfowl commented Aug 8, 2020

Remaining warnings:

C:\dev\git\aspnetcore\src\Security\Authentication\OAuth\src\OAuthHandler.cs(38,15): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler<TOptions>.OAuthHandler`1(IOptionsMonitor<OAuthHandler<TOptions>.TOptions>,ILoggerFactory,UrlEncoder,ISystemClock): The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]
C:\dev\git\aspnetcore\src\Security\Authentication\Core\src\RemoteAuthenticationHandler.cs(35,15): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.RemoteAuthenticationHandler`1(IOptionsMonitor<RemoteAuthenticationHandler<TOptions>.TOptions>,ILoggerFactory,UrlEncoder,ISystemClock): The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]
C:\dev\git\aspnetcore\src\Security\Authentication\Core\src\AuthenticationHandler.cs(19,68): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>.AuthenticationHandler`1(IOptionsMonitor<AuthenticationHandler<TOptions>.TOptions>,ILoggerFactory,UrlEncoder,ISystemClock): The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]

dotnet/linker#1416 - - Compiler generated generic parameters

C:\dev\git\aspnetcore\src\Security\Authentication\Core\src\AuthenticationBuilder.cs(36,21): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0<TOptions,THandler>.<AddSchemeHelper>b__2(AuthenticationSchemeBuilder): The generic parameter 'THandler' from 'Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0<TOptions,THandler>' with dynamically accessed member kinds 'None' is passed into the parameter 'value' of method 'Microsoft.AspNetCore.Authentication.AuthenticationSchemeBuilder.set_HandlerType(Type)' which requires dynamically accessed member kinds 'PublicConstructors'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicConstructors'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]

dotnet/linker#1403 - Compiler generated backing fields

ILLink : Trim analysis warning IL2006: Microsoft.Extensions.Options.IOptionsMonitor`1<TOptions> Microsoft.AspNetCore.Authentication.AuthenticationHandler`1::<OptionsMonitor>k__BackingField: The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]

Mostly constructors and compiler generated code.

- Preserve constructors whereever open generics or type arguments exist
@davidfowl davidfowl requested a review from eerhardt August 8, 2020 21:19
@davidfowl davidfowl added the linker-friendliness Tracking linker friendliness label Aug 9, 2020
@davidfowl davidfowl added this to the 5.0.0-rc1 milestone Aug 9, 2020
@davidfowl
Copy link
Member Author

davidfowl commented Aug 9, 2020

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var bar = new Bar<MyThing>(new Lazy<MyThing>());
            Console.WriteLine(bar.ToString());
        }
    }

    public class MyThing
    {

    }

    public class Bar<T> where T : new()
    {
        public Bar(Lazy<T> lazy)
        {

        }
    } 
}
C:\Users\davifowl\source\repos\WebApplication60\ConsoleApp1\Program.cs(26,9): Trim analysis warning IL2006: ConsoleApp1.Bar<T>.Bar`1(Lazy<Bar<T>.T>): The generic parameter 'T' from 'ConsoleApp1.Bar<T>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'T' from 'System.Lazy<T>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\ConsoleApp1\ConsoleApp1.csproj]

This seems like a linker bug. It's asking me to do this:

public class Bar<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T> where T : new()
{
    public Bar(Lazy<T> lazy)
    {

    }
}

But that should be inferred from the new constraint. Maybe the same issue as this dotnet/linker#1412?

cc @marek-safar @MichalStrehovsky @vitek-karas

@@ -50,6 +51,7 @@ public AuthenticationScheme(string name, string? displayName, Type handlerType)
/// <summary>
/// The <see cref="IAuthenticationHandler"/> type that handles this scheme.
/// </summary>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the attribute do anything when the property isn't settable?

Copy link
Member Author

@davidfowl davidfowl Aug 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's tracked via the constructor assignment when the linker does flow control.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The annotation works both ways:

  • When assigned to, linker makes sure the input satisfies the requirements - so either it needs to have a similar annotation or it's a statically recognized type for which linker then includes public .ctors.
  • When read from - if the value of the property is passed to another method and that methods also has the attribute, linker will compare the attributes and if they're compatible it won't issue a warning since it knows that types stored in the property fulfill the requirements

@@ -16,6 +17,8 @@ public abstract class AuthenticationHandler<TOptions> : IAuthenticationHandler w
private Task<AuthenticateResult>? _authenticateTask;

public AuthenticationScheme Scheme { get; private set; } = default!;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
Copy link
Member

@JamesNK JamesNK Aug 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the attribute do anything when the property isn't (publically) settable?

Curious why the attribute is here and not on the TOptions generic arg on the class.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good question. It probably doesn't need to be on here but the linker complains about the backing field for the property. It's possible this attribute should automagically flow to the compiler generated backing field to avoid that.

The other thing is that we have a new constraint so this shouldn't be needed at all... Likely a linker issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird - the attribute on this property doesn't make any sense - it should only be on properties of type System.Type or System.String. Linker currently doesn't warn about this (I think it should - dotnet/linker#1420) - but in reality it will simply ignore the attribute in this case.

I don't know what the original warning was about the backing field you mention. If it has to do with TOptions then the attribute should be on the generic parameter. (with the linker fix it might not be needed due to the new constraint anyway).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove these on the properties

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove these on the properties

It's just this one place that is an issue, right?

with the linker fix it might not be needed due to the new constraint anyway

That fix has been checked in (dotnet/linker#1414). @davidfowl - can you try the latest mono/linker and see if the warning just goes away here?

@MichalStrehovsky
Copy link
Member

But that should be inferred from the new constraint. Maybe the same issue as this dotnet/linker#1412?

Yeah, looks like the same issue. We have a fix, but it has been waiting for Vitek to come back from vacation.

@@ -50,6 +51,7 @@ public AuthenticationScheme(string name, string? displayName, Type handlerType)
/// <summary>
/// The <see cref="IAuthenticationHandler"/> type that handles this scheme.
/// </summary>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The annotation works both ways:

  • When assigned to, linker makes sure the input satisfies the requirements - so either it needs to have a similar annotation or it's a statically recognized type for which linker then includes public .ctors.
  • When read from - if the value of the property is passed to another method and that methods also has the attribute, linker will compare the attributes and if they're compatible it won't issue a warning since it knows that types stored in the property fulfill the requirements

@@ -16,6 +17,8 @@ public abstract class AuthenticationHandler<TOptions> : IAuthenticationHandler w
private Task<AuthenticateResult>? _authenticateTask;

public AuthenticationScheme Scheme { get; private set; } = default!;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird - the attribute on this property doesn't make any sense - it should only be on properties of type System.Type or System.String. Linker currently doesn't warn about this (I think it should - dotnet/linker#1420) - but in reality it will simply ignore the attribute in this case.

I don't know what the original warning was about the backing field you mention. If it has to do with TOptions then the attribute should be on the generic parameter. (with the linker fix it might not be needed due to the new constraint anyway).

@eerhardt
Copy link
Member

Remaining warnings:

C:\dev\git\aspnetcore\src\Security\Authentication\OAuth\src\OAuthHandler.cs(38,15): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler<TOptions>.OAuthHandler`1(IOptionsMonitor<OAuthHandler<TOptions>.TOptions>,ILoggerFactory,UrlEncoder,ISystemClock): The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]
C:\dev\git\aspnetcore\src\Security\Authentication\Core\src\RemoteAuthenticationHandler.cs(35,15): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.RemoteAuthenticationHandler`1(IOptionsMonitor<RemoteAuthenticationHandler<TOptions>.TOptions>,ILoggerFactory,UrlEncoder,ISystemClock): The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]
C:\dev\git\aspnetcore\src\Security\Authentication\Core\src\AuthenticationHandler.cs(19,68): Trim analysis warning IL2006: Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>.AuthenticationHandler`1(IOptionsMonitor<AuthenticationHandler<TOptions>.TOptions>,ILoggerFactory,UrlEncoder,ISystemClock): The generic parameter 'TOptions' from 'Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'TOptions' from 'Microsoft.Extensions.Options.IOptionsMonitor<TOptions>' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [C:\Users\davifowl\source\repos\WebApplication60\WebApplication60\WebApplication60.csproj]

Why can't these be addressed?

@davidfowl
Copy link
Member Author

Because the new constraint should take care of them.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Pilchie Pilchie added the area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer label Aug 10, 2020
@davidfowl davidfowl merged commit 0e592df into master Aug 10, 2020
@davidfowl davidfowl deleted the davidfowl/linker-auth branch August 10, 2020 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer linker-friendliness Tracking linker friendliness
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants