如何在 .net 核心上配置 AddAuthorization 以允许多个令牌提供者的角色?

How to config AddAuthorization on .net core in order to allow roles for multiple token providers?

我正在构建一个 API,它需要使用其控制器 [Authorize(Roles = "A1, A2")] 上的 OpenIddict 或 ADFS 和包含者角色生成的自己的令牌进行身份验证。但是,如果添加任何非默认选项,角色将不起作用:

我的 startup.cs ConfigureServices 方法

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
    options.Authority = authenticationOptions.Issuer;
    options.Audience = authenticationOptions.Audience;
    options.RequireHttpsMetadata = !hostingEnvironment.IsDevelopment();
    options.IncludeErrorDetails = true;
    options.SaveToken = true;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateLifetime = true,
        ValidateIssuer = true,
        ValidIssuer = authenticationOptions.Issuer,
        ValidateAudience = true,
        ValidAudience = authenticationOptions.Audience,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new X509SecurityKey(LoadCertificate(services))
    };
})
.AddJwtBearer("ADFS", options =>
{
    options.Authority = appSettings.AdfsAuthority;
    options.Audience = appSettings.AdfsAudience;
    options.IncludeErrorDetails = true;
    options.MetadataAddress = appSettings.AdfsMetadataAddress;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateLifetime = true,
        ValidateIssuer = true,
        ValidIssuer = appSettings.AdfsIssuer,
        ValidateAudience = true,
        ValidAudience = appSettings.AdfsAudience,
        ValidateIssuerSigningKey = true
    };
});

services.AddAuthorization(options =>
{
    options.AddPolicy("A2", policy => policy.RequireRole("A2"));
    //options.AddPolicy("A1", policy => policy.RequireRole("A1"));

    var policies = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme, "ADFS")
        .RequireAuthenticatedUser()
        .RequireRole("A1")
        .Build();

    options.DefaultPolicy = policies;
});

如果我只使用一个 AddJwtBearer 供应商,则角色政策如下:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
    options.Authority = authenticationOptions.Issuer;
    options.Audience = authenticationOptions.Audience;
    options.RequireHttpsMetadata = !hostingEnvironment.IsDevelopment();
    options.IncludeErrorDetails = true;
    options.SaveToken = true;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateLifetime = true,
        ValidateIssuer = true,
        ValidIssuer = authenticationOptions.Issuer,
        ValidateAudience = true,
        ValidAudience = authenticationOptions.Audience,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new X509SecurityKey(LoadCertificate(services))
    };
});

services.AddAuthorization(options =>
{
    options.AddPolicy("A2", policy => policy.RequireRole("A2"));
});

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
    options.Authority = appSettings.AdfsAuthority;
    options.Audience = appSettings.AdfsAudience;
    options.IncludeErrorDetails = true;
    options.MetadataAddress = appSettings.AdfsMetadataAddress;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateLifetime = true,
        ValidateIssuer = true,
        ValidIssuer = appSettings.AdfsIssuer,
        ValidateAudience = true,
        ValidAudience = appSettings.AdfsAudience,
        ValidateIssuerSigningKey = true
    };
});

services.AddAuthorization(options =>
{
    options.AddPolicy("A1", policy => policy.RequireRole("A1"));
});

有人可以帮忙吗?我猜问题出在 AddAuthorization 上,因为不知何故 RequireRole 配置始终应用于默认架构,在这种情况下它从未应用于自定义的“ADFS”。

我已经对它进行了排序更改授权过滤器以添加像 [Authorize(AuthenticationSchemes = "ADFS, Bearer", Roles = "A1, A2")] 这样的 AuthenticationSchemes 我不得不更新 AddAuthorization

services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .AddAuthenticationSchemes("ADFS", JwtBearerDefaults.AuthenticationScheme)
        .Build();
});