Asp.net core 在.NETCore中使用双重授权(承载和基本)时获得403

Asp.net core 在.NETCore中使用双重授权(承载和基本)时获得403,asp.net-core,authorization,Asp.net Core,Authorization,我有一个例子,我希望使用承载令牌进行身份验证和基本身份验证,但每次使用基本身份验证时,我都会得到一个403禁止([Authorize(authorization(authorizationschemes=“BasicAuthentication”)]) 。 这是我的startup.cs: services .AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearer

我有一个例子,我希望使用承载令牌进行身份验证和基本身份验证,但每次使用基本身份验证时,我都会得到一个403禁止([Authorize(authorization(authorizationschemes=“BasicAuthentication”)])

。 这是我的startup.cs:

services
    .AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

    })
    .AddJwtBearer(cfg =>
    {
        cfg.RequireHttpsMetadata = false;
        cfg.SaveToken = true;
        cfg.TokenValidationParameters = new TokenValidationParameters
        {
            ...
        };
    })
    .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);

services.AddAuthorization(options =>
{

    options.AddPolicy("BasicAuthentication",
        authBuilder =>
        {
            authBuilder.AddAuthenticationSchemes("BasicAuthentication");
            authBuilder.RequireClaim("NameIdentifier");

        });
});
            services
            .AddBasicAuthorization()
            .AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            })
            .AddJwtBearer(cfg =>
            {
                cfg.RequireHttpsMetadata = false;
                cfg.SaveToken = true;
                cfg.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer = Configuration["JwtIssuer"],
                    ValidAudience = "Audience",
                    ValidateLifetime = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
                    ValidateIssuerSigningKey = true,
                    ClockSkew = TimeSpan.Zero // remove delay of token when expire
                };
            });
服务
.AddAuthentication(选项=>
{
options.DefaultAuthenticateScheme=JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme=JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme=JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg=>
{
cfg.RequireHttpsMetadata=false;
cfg.SaveToken=true;
cfg.TokenValidationParameters=新的TokenValidationParameters
{
...
};
})
.AddScheme(“基本验证”,null);
services.AddAuthorization(选项=>
{
options.AddPolicy(“基本验证”,
authBuilder=>
{
authBuilder.AddAuthenticationSchemes(“基本身份验证”);
authBuilder.Requireclain(“名称标识符”);
});
});
我为Basic添加了一个处理程序:

public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (!Request.Headers.ContainsKey("Authorization"))
            return AuthenticateResult.Fail("Missing Authorization Header");

        ...

        var claims = new[] {
            new Claim(ClaimTypes.NameIdentifier, username),
            new Claim(ClaimTypes.Role, "User"),
            new Claim(ClaimTypes.Name, username)
        };

        var identity = new ClaimsIdentity(claims, Scheme.Name);

        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, Scheme.Name);

        return AuthenticateResult.Success(ticket);
    }
}
公共类BasicAuthenticationHandler:AuthenticationHandler
{
受保护的重写异步任务handleAuthenticateAync()
{
if(!Request.Headers.ContainsKey(“授权”))
返回AuthenticateResult.Fail(“缺少授权标头”);
...
风险值索赔=新[]{
新索赔(ClaimTypes.NameIdentifier,用户名),
新索赔(ClaimTypes.Role,“用户”),
新索赔(ClaimTypes.Name、用户名)
};
var标识=新的索赔实体(索赔、方案、名称);
var principal=新的ClaimsPrincipal(身份);
var票证=新的身份验证票证(主体,Scheme.Name);
返回AuthenticateResult.Success(票证);
}
}

处理程序返回正确案例的成功,但仍返回403。

这是因为在构造标识时错过了
authenticationType
参数:

var claims = new[] { new Claim(ClaimTypes.NameIdentifier, username), new Claim(ClaimTypes.Role, "User"), new Claim(ClaimTypes.Name, username) }; var identity = new ClaimsIdentity(claims); var identity = new ClaimsIdentity(claims,Scheme.Name); 风险值索赔=新[]{ 新索赔(ClaimTypes.NameIdentifier,用户名), 新索赔(ClaimTypes.Role,“用户”), 新索赔(ClaimTypes.Name、用户名) }; var标识=新的索赔实体(索赔); var标识=新的索赔实体(索赔、方案、名称);
我可以通过更改设置来解决此问题:我创建了一个扩展方法,用于添加策略和authenticationhandler:

    public static class BasicAuthExtensions
{
    public static IServiceCollection AddBasicAuthorization(this IServiceCollection serviceCollection)
    {
        serviceCollection
        .AddAuthorization(options =>
        {
            options.AddBasicPolicy();
        })
        .AddAuthentication("BasicAuthentication")
        .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);

        return serviceCollection;
    }

    public static AuthorizationOptions AddBasicPolicy(this AuthorizationOptions options)
    {
        var policy = new AuthorizationPolicyBuilder()
            .AddAuthenticationSchemes("BasicAuthentication")
            .RequireAuthenticatedUser()
            .Build();

        options.AddPolicy("BasicPolicy", policy);
        return options;
    }
}

谢谢你的回答,我认为你是对的,但似乎不止一个问题。我添加了方案名称,但仍然得到403。@Arnstein事实上,我已经测试了上面的代码,它按预期工作。如果您以前登录过,请先注销。如果你仍然得到403,请随时更新我。