在.net Core中使用双重授权(Bearer和Basic)时获得403

时间:2019-02-07 13:59:16

标签: asp.net-core authorization

在某些情况下,我既需要使用Bearer令牌进行身份验证,又需要进行Basic身份验证,但是每次使用Basic时都会收到403 Forbidden([Authorize(AuthenticationSchemes =“ 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");

        });
});

并且我为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);
    }
}

在正确的情况下,处理程序将返回成功,但仍返回403。

2 个答案:

答案 0 :(得分:1)

那是因为在构造标识时您错过了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);

答案 1 :(得分:0)

我能够通过更改设置来解决它:我创建了扩展方法来添加我的策略和身份验证处理程序:

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

然后我将其添加到startup.cs中:

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