IClaimsTransformation 未被调用

问题描述 投票:0回答:4

我正在开发 ASP.NET Core Web 应用程序 (.NET 5.0)。 这是一个 Intranet 应用程序,因此我使用 Windows 身份验证。 对于授权,我使用 AspNetCore.Identity 中的自定义角色(出于各种原因不想使用 AD 组)。 我正在使用

IClaimsTransformation
类来实现
TransformAsync
方法,以便将我的自定义角色添加到用户的声明中。 我在控制器上添加了
[Authorize(Roles = "Admin")]
来测试整个方案。

当我在调试(IIS Express)中测试时,永远不会调用

TransformAsync
方法。

我确实在我的

launchSettings.json
中检查了 IIS 是否启用了 Windows 身份验证:

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

我还检查了是否为调试模式启用了 windowsAuthentication (IIS Express): 在此输入图片描述

以下是我的

ConfigureServices
方法(
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>();

        }

这是我的

Configure
方法(
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?}");
            });
        }

这就是

TransformAsync
方法:

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 
        }
  }

我尝试按照此

post
中的建议更改
services.AddAuthentication(IISDefaults.AuthenticationScheme)
中的顺序startup.cs,但这并没有解决问题。

我错过了什么?

asp.net-core asp.net-identity
4个回答
7
投票

我终于找到了自己问题的解决方案。 解决方案是在

services.AddAuthentication()
方法 (
ConfigureServices
) 中更改对
startup.cs
的调用,如下所示:

之前:

services.AddAuthentication(IISDefaults.AuthenticationScheme);

之后:

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

这是

ConfigureServices
方法的完整代码(
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;
     });
}

1
投票

我知道这是一个较旧的线程。我遇到过同样的问题。我注意到,当调用客户端没有为我的 API 指定任何范围时,IClaimsTransformer 不会被调用。我在服务中添加了一项策略,要求至少声明一个默认范围,现在它按预期工作。

services.AddAuthorization(options => {
            List<string> requiredScopes = Configuration.GetSection("RequiredScopes")?.GetChildren().Select(x => x.Value).ToList();
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .RequireScope(requiredScopes)
                .Build();
            options.AddPolicy("Security Requirements", policy);
        });

1
投票

当您使用身份时,您必须在服务中的身份之后添加此行

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

因为身份使用了自己的身份验证

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

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

            //ASP Identity
            services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();
            services.AddAuthentication(opt => {
                opt.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = IISDefaults.AuthenticationScheme;
            });

        }

0
投票

这个线程可能很旧,但我认为所有答案都无法找出问题,因此并没有真正解决问题。

在 ASP.NET Core 中,仅当满足以下所有条件时才应用

IClaimsTransformation
实例:

  • 服务中启用了身份验证,
  • IClaimsTransformation
    实例已在依赖注入系统中注册,
  • 基于任何身份验证方案已成功对请求进行身份验证,
  • a
    ClaimsPrincipal
    已设置(重要,如果您使用自定义身份验证方案)。

参考:ASP.NET Core 8 ./src/Http/Authentication.Core/src/AuthenticationService.cs

© www.soinside.com 2019 - 2024. All rights reserved.