在某些情况下,我既需要使用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。
答案 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
};
});