如果你能理解错误的原因可能会更好,所以我会在这里解释一下。
我们都使用
app.UseAuthentication();
in-out startup类,它的幕后流程如下
this
.
在上述配置中,您提供了中间件2方案来进行处理
services.AddAuthentication()
.AddCookie()
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
var secretKey = Configuration.GetSection("JWTSettings:SecretKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = Configuration.GetSection("JWTSettings:Issuer").Value,
ValidateAudience = true,
ValidAudience = Configuration.GetSection("JWTSettings:Audience").Value,
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
};
});
第一个是
CookieAuthenticationDefaults.AuthenticationScheme
第二个是
JwtBearerDefaults.AuthenticationScheme
.
然后他们都得到了execute(我知道你指出了方案,但你没有设置默认方案,所以
Schemes.GetDefaultAuthenticateSchemeAsync()
将返回可能不是我们想要的东西)。
解决方案:使用默认方案,并提出一些逻辑来将管道转发给正确的处理器!
services.AddAuthentication(opts =>
{
opts.DefaultScheme = "multi-scheme-election";
opts.DefaultChallengeScheme = "multi-scheme-election";
})
.AddCookie()
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
var secretKey = configuration.GetSection("JWTSettings:SecretKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = configuration.GetSection("JWTSettings:Issuer").Value,
ValidateAudience = true,
ValidAudience = configuration.GetSection("JWTSettings:Audience").Value,
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey
};
})
.AddPolicyScheme("multi-scheme-election", "Your Election scheme processor here",
cfgOpts => cfgOpts.ForwardDefaultSelector = ctx =>
ctx.Request.Headers.ContainsKey("Authorization")
? JwtBearerDefaults.AuthenticationScheme
: CookieAuthenticationDefaults.AuthenticationScheme);
好了,试试看
[HttpGet("TestAuthentication")]
[Authorize] // No need to specify the scheme here, the default policy will take us the right one
public IActionResult TestAuthentication()
{
return Ok("Authenticated!");
}
P/s:我现在也在用这个。