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

IClaimsTransformation - TransformAsync Never Called in Net Core 3.1 #18040

Closed
ghost opened this issue Dec 26, 2019 · 15 comments
Closed

IClaimsTransformation - TransformAsync Never Called in Net Core 3.1 #18040

ghost opened this issue Dec 26, 2019 · 15 comments
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Status: Resolved

Comments

@ghost
Copy link

ghost commented Dec 26, 2019

I have many apps running under Net Core 2.2 that use a ClaimsTransformation to add application specific user claims to a use.

I am creating a new up under Net Core 3.1 and attempting to use the same strategy, but it fails, TransformAsync is never called.

This has been brought up before, but there was no real solution, only that playing with the order of the services sometimes worked and the issue was closed.

Startup Class

    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment Env)
        {
            Configuration = configuration;

            var config = new ConfigurationBuilder()
                .SetBasePath(Env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEntityFrameworkConfig(Configuration)
                .Build ();

            Configuration = config;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            services.AddAuthentication(IISDefaults.AuthenticationScheme);

            services.AddScoped<IClaimsTransformation, ClaimsTransformer>();

            services.AddDbContext<DataDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DataConnection")));

            services.AddDbContext<IDDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("IDConnection")));


            string ApplicationName = Configuration.GetSection("ApplicationInformation")["AppDotName"];

            services.AddAuthorization(options =>
                {
                    options.AddPolicy("IT", policy => policy.RequireClaim(ApplicationName, "IT"));
                    options.AddPolicy("AppUser", policy => policy.RequireClaim(ApplicationName, "Application User - Entry Level"));
                });

            services.Configure<IISOptions>(Options =>
                Options.AutomaticAuthentication = true);

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<IDDbContext>();

            services.AddSingleton(Configuration);

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            services.AddAutoMapper(typeof(Startup));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseAuthentication();
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Claims Transformation Class

    public class ClaimsTransformer : IClaimsTransformation
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly IConfiguration _configuration;

        public ClaimsTransformer(UserManager<ApplicationUser> UserManger, IConfiguration Configuration)
        {
            _userManager = UserManger;
            _configuration = Configuration;
        }
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            string AppDotName = _configuration.GetSection("ApplicationInformation")["AppDotName"];
            ApplicationUser User = new ApplicationUser();

            string UMName = principal.Identity.Name.Split((char)92).Last() + "@leedo.com";
            try
            {
                User = await _userManager.FindByNameAsync(UMName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            IList<Claim> UserClaims = await _userManager.GetClaimsAsync(User);

            List<Claim> ClaimsToAdd = UserClaims.Where(c => c.Type == AppDotName).ToList();

            foreach(Claim NC in ClaimsToAdd)
            {
                if(!principal.HasClaim(NC.Type, NC.Value))
                {
                    (principal.Identity as ClaimsIdentity).AddClaim(NC);
                }
            }
            return principal;
        }
    }

The Claims Transformer's constructor is called as expected, but TransformAsync is not.

I have searched the web, but most references are back to Net Core 2.2 or earlier and there, it works.

Further technical details

  • ASP.NET Core version - 3.1.0

  • The IDE VS Pro 16.4.2

  • dotnet --info
    PM> dotnet --info
    .NET Core SDK (reflecting any global.json):
    Version: 3.1.100
    Commit: cd82f021f4

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.100\

Host (useful for support):
Version: 3.1.0
Commit: 65f04fb6db

.NET Core SDKs installed:
1.1.0 [C:\Program Files\dotnet\sdk]
1.1.5 [C:\Program Files\dotnet\sdk]
1.1.6 [C:\Program Files\dotnet\sdk]
1.1.7 [C:\Program Files\dotnet\sdk]
1.1.8 [C:\Program Files\dotnet\sdk]
1.1.9 [C:\Program Files\dotnet\sdk]
1.1.10 [C:\Program Files\dotnet\sdk]
1.1.11 [C:\Program Files\dotnet\sdk]
1.1.12 [C:\Program Files\dotnet\sdk]
1.1.13 [C:\Program Files\dotnet\sdk]
1.1.14 [C:\Program Files\dotnet\sdk]
2.0.2 [C:\Program Files\dotnet\sdk]
2.0.3 [C:\Program Files\dotnet\sdk]
2.1.2 [C:\Program Files\dotnet\sdk]
2.1.4 [C:\Program Files\dotnet\sdk]
2.1.100 [C:\Program Files\dotnet\sdk]
2.1.101 [C:\Program Files\dotnet\sdk]
2.1.102 [C:\Program Files\dotnet\sdk]
2.1.103 [C:\Program Files\dotnet\sdk]
2.1.104 [C:\Program Files\dotnet\sdk]
2.1.200 [C:\Program Files\dotnet\sdk]
2.1.201 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.300 [C:\Program Files\dotnet\sdk]
2.1.302 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.500 [C:\Program Files\dotnet\sdk]
2.1.502 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.504 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.507 [C:\Program Files\dotnet\sdk]
2.1.508 [C:\Program Files\dotnet\sdk]
2.1.602 [C:\Program Files\dotnet\sdk]
2.1.604 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.801 [C:\Program Files\dotnet\sdk]
2.1.802 [C:\Program Files\dotnet\sdk]
2.2.102 [C:\Program Files\dotnet\sdk]
2.2.104 [C:\Program Files\dotnet\sdk]
2.2.105 [C:\Program Files\dotnet\sdk]
2.2.203 [C:\Program Files\dotnet\sdk]
2.2.300 [C:\Program Files\dotnet\sdk]
2.2.401 [C:\Program Files\dotnet\sdk]
2.2.402 [C:\Program Files\dotnet\sdk]
3.1.100 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3-servicing-26724-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

@blowdart blowdart added the area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer label Dec 26, 2019
@Tratcher
Copy link
Member

That ordering should be:

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>

Why are you modifying these claims per-request rather than adding them to the user at sign-in so they'll be persisted in the auth cookie?

@ghost
Copy link
Author

ghost commented Dec 26, 2019

Chris,
Changing the order had no effect. The TransformAsync still is never called.

Regarding claims per request v sign-in, I am open to any and all suggestions that will make this work. So far hours playing with order of the app. entries and service entries and reading had lead nowhere.

@ghost
Copy link
Author

ghost commented Dec 30, 2019

To try to get more information, I injected IAuthorizationServer and called .AuthorizeAsync(...) and TransformAsync in the IClaimsTransformation is never called.

Injecting IClaimsTransformation and manually calling TransformAsync(...) does indeed call TransformAsnc which works as it should.

It seems like the Default Authorization Service isn't doing what it is supposed to and calling TransformAsync.

@Tratcher
Copy link
Member

Tratcher commented Jan 2, 2020

Here's where TransformAsync is expected to be called:
https://github.com/aspnet/AspNetCore/blob/c7937640a4079465d36441724933eae5a9ca0085/src/Http/Authentication.Core/src/AuthenticationService.cs#L80-L95

Is AuthenticateAsync returning a result with Succeeded set?

The only other thing that would prevent this is the new transform cache which is designed to prevent transformation from running multiple times.

To try to get more information, I injected IAuthorizationServer and called .AuthorizeAsync(...) and TransformAsync in the IClaimsTransformation is never called.

Where did you try this? In a controller? The transform cache would prevent TransformAsync from running multiple times. A better test would be to call AuthenticateAsync in a middleware early in your app pipeline.

@ghost
Copy link
Author

ghost commented Jan 2, 2020

I am not running AuthenticateAync manually anywhere, however looking at httpcontext.user.identity, IsAuthenticated is true so it would seem the AuthenticateAsync is being run, and the user is authenticated. From the code above, yes it would seem that it is the Transform Cache causing the issue, but I am not sure how to go about proving that.

I set up the TransformAsync and AuthorizeAsync in a controller for test purposes only. I wanted them somewhere where I could verify that the user was authenticated, that the transform actually did what it was supposed to and that AuthorizeAsync behaved as expected.

Do you have something specific that you want me to try as middleware and, if so, where it should be?

Any ideas how to check the transform cache?

Does this matter if the app is using Windows authentication?

@analogrelay
Copy link
Contributor

It sounds like we're getting a little stuck in debugging :). @GRS-Leedo can you provide a runnable sample app that reproduces the problem you're seeing?

@Tratcher 's earlier suggestion was to have a custom middleware in the pipeline before UseAuthentication and call IAuthorizationService.AuthorizeAsync there.

Does this matter if the app is using Windows authentication?

Yes, this can matter, but we need clarification on what server you are using (IIS/HttpSysServer/Kestrel/etc.).

A repro app is really the best way to get clarity here so we can see the whole context rather than having to toss debugging steps back and forth ;).

@analogrelay analogrelay added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label Jan 2, 2020
@ghost
Copy link
Author

ghost commented Jan 2, 2020

While I understand that a repro app is helpful, I have production deadlines to meet and writing a repro app from scratch will take time. I have already lost many hours trying to get this to work and have had to revert from Net Core 3.1 back to 2.26 in order to move forward on developing my current app. The truly frustrating part is that claims transformation has run fine through many versions of Net Core 2, but 3.1 breaks it. I purposefully skipped 3.0 figuring that the kinks would get worked out for 3.1.

When I get some time, I will work on a repro app. I have not written much middleware so that isn't something that I can just whip up.

I am using VS2019 Pro and the test app runs under IIS Express during debug with Windows Authentication.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Jan 2, 2020
@ghost
Copy link
Author

ghost commented Jan 3, 2020

ClaimsTest.zip
Ok, here is a bare bones project that I threw together. It exhibits the same issue.

I ran the app first with no policy requirement on the Home Controller, just Authorize. The app behaved as expected except TransformAsync is never called.

I then added the policy requirement to the Home Controller and the app responds with Access Denied and again, TransformAsyc is never called.

Does the _transformCache persist in any way? Is it stored as a cookie in the browser?

@ghost
Copy link
Author

ghost commented Jan 3, 2020

Did the file get attached? If not, here it is again.
ClaimsTest.zip

@Tratcher
Copy link
Member

Tratcher commented Jan 3, 2020

Thanks, we'll give it a try.

The _transformCache is a per-request cache designed to prevent redundant transformations. It should never cache across requests.

@Tratcher
Copy link
Member

Tratcher commented Jan 3, 2020

Ok, I see the trouble. Your app has both Identity and Windows Auth enabled, and Identity is winning.

            services.AddAuthentication(IISDefaults.AuthenticationScheme);

vs.

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<IDDbContext>();

AddAuthentication sets the DefaultScheme (Windows), but AddIdentity sets the DefaultAuthenticateScheme (Identity.Application) which takes priority for the Auth middleware. You're not logged in using Identity cookies so claims transformation doesn't run. Commenting out AddIdentity gets you back to Windows auth and allows transformations to run. Setting DefaultAuthenticateScheme to IISDefaults.AuthenticationScheme after AddIdentity also fixes it.

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
            });

Setting IISDefaults.AuthenticationScheme on your authorization policy would also do it.

options.AddPolicy("IT", policy => policy.RequireClaim("test", "it").AddAuthenticationSchemes(IISDefaults.AuthenticationScheme));

@analogrelay
Copy link
Contributor

@GRS-Leedo Let us know if that resolves your issue! If not, we can investigate further.

@analogrelay analogrelay added Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels Jan 3, 2020
@satininus
Copy link

@Tratcher Thanks so much! I was updating from 2.2 to 3.0 this morning and experienced the same issue described above. I followed your instructions and that worked perfectly.

@ghost
Copy link
Author

ghost commented Jan 3, 2020

My actual claims transformer needs identity so commenting out Add Identity didn't work. Moving Add Authentication to after Add Identity did work.
` services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores();

        services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
            });`

With this change, my app runs. Thank you very much. I am going to look at refactoring my Claims Transformation to not rely on identity, so that I can remove the Add Identity entirely.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Jan 3, 2020
@Tratcher
Copy link
Member

Tratcher commented Jan 3, 2020

Note the behavior that changed here between 2.2 and 3.0 is probably related to #11390 rather than anything to do with the the new transform cache. Out-of-proc used to call AuthenticateAsync(Windows) at the start of every request which would result in claims transformation running. That no longer happens in 3.0. The other change was that in-proc is now the default mode and it never did call AuthenticateAsync(Windows) at the start of the pipeline like out-of-proc used to.

@Tratcher Tratcher closed this as completed Jan 3, 2020
@Tratcher Tratcher added ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels Jan 3, 2020
@ghost ghost added the Status: Resolved label Jan 3, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Feb 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Status: Resolved
Projects
None yet
Development

No branches or pull requests

4 participants