IClaimsTransformation not being called

Viewed 2680

I am developing an ASP.NET Core Web app (.NET 5.0). This is an intranet app, so I am using Windows Authentication. For Authorization, I am using custom roles from AspNetCore.Identity (don't want to use AD groups for various reasons). I am using the IClaimsTransformation class to implement a TransformAsync method in order to add my custom roles to the user's claim. I added the [Authorize(Roles = "Admin")] on a controller to test the whole scheme.

When I test in Debug (IIS Express), the TransformAsync method never gets called.

I did check that Windows Authentication is enabled for IIS in my launchSettings.json:

  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:49861",
      "sslPort": 44307
    }

I also checked that windowsAuthentication is enabled for Debug mode (IIS Express): enter image description here

Below is my ConfigureServices method (startup.cs) :

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>
                (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            
            services.AddControllersWithViews();

            // Windows Authentication
            services.AddAuthentication(IISDefaults.AuthenticationScheme);

            // Claim transformation
            services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();

            //ASP Identity
            services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();

        }

and this is my Configure method (startup.cs) :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

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

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

and this is the TransformAsync method :

public class AddRolesClaimsTransformation : IClaimsTransformation
    {
        private readonly UserManager<ApplicationUser> _userManager;

        public AddRolesClaimsTransformation(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }

        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            //code removed for simplicity - this never gets called 
        }
  }

I tried changing the order services.AddAuthentication(IISDefaults.AuthenticationScheme) in startup.cs as suggested in this post but this did not solve the problem.

What am I missing ?

1 Answers

I finally found a solution to my own question. The solution was to change the call to services.AddAuthentication() in ConfigureServices method (startup.cs) as follows:

BEFORE:

services.AddAuthentication(IISDefaults.AuthenticationScheme);

AFTER:

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

This is the full code for ConfigureServices method (startup.cs):

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>
                (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            
    services.AddControllersWithViews();

    //ASP Identity
    services.AddIdentity<ApplicationUser, IdentityRole> 
    ().AddEntityFrameworkStores<ApplicationDbContext>();

    // Claim transformation
    services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();

    // Windows Authentication
    services.AddAuthentication(options =>
     {
       options.DefaultAuthenticateScheme =  IISDefaults.AuthenticationScheme;
     });
}
Related