我是 ASP.NET Core 的初学者,特别是 ASP.NET Core 6.0。我尝试按照教程在我当前的 Web API(not minimal)项目中设置 Identity + JWT 身份验证和授权,尽管到目前为止它可以使用基本登录/注册,但有一件事困扰我,我还没有找到在教程或任何 SO 问题中回答。
我必须在每个控制器操作的
AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
属性中添加 [Authorize(...)]
,否则它们都会返回 404 空结果,即使具有正确的身份验证 + 授权(如果有)。
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using FluentValidation;
using Capstone.ExceptionHandling;
using Capstone.Data;
using Capstone.Models;
using Capstone.Features;
using Capstone.Features.ApplicantModule;
using Capstone.Features.EmployeeModule;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Capstone.Features.Auth;
using Capstone.Features.Auth.Models;
var builder = WebApplication.CreateBuilder(args);
// ... irrelevant
// ---- Auth ----
builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
ValidIssuer = builder.Configuration.GetSection("JWT:ValidIssuer").Value,
ValidAudience = builder.Configuration.GetSection("JWT:ValidAudience").Value,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
builder.Configuration.GetSection("JWT:SecretKey").Value
))
};
});
builder.Services
.AddIdentity<AuthUser, IdentityRole>(options =>
{
options.User.RequireUniqueEmail = true;
options.Password.RequiredLength = 8;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
})
.AddEntityFrameworkStores<CapstoneContext>();
builder.Services.AddScoped<IValidator<RegisterRequest>, RegisterRequestValidator>();
// ... irrelevant
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors("Capstone");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
有没有办法在我的项目中全局设置这个?
我已经尝试了在线建议的多个修复程序,例如手动设置
AddAuthentication
选项(DefaultScheme, DefaultAuthenticationScheme, DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme
)而不是仅仅通过JwtBearerDefaults.AuthenticationScheme
,并检查我对Use...
调用的排序,例如保证UseAuthentication
在UseAuthorization
之前进行
,虽然这些通常会提到 UseRouting
或 UseMvc
但我的项目没有那些。
我只是不想在控制器的操作方法的
AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
属性中提供[Authorize(...)]
。
我找到了问题和解决方法,但我不知道真正导致它的原因。
查看控制台时,在发出请求后,您可以看到:
错误: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9] AuthenticationScheme:Identity.Application 未通过身份验证。
这是我最初的怀疑:配置了另一个默认处理程序。
如果您查看
AddIdentity<TUser, TRole>
的源代码,您将看到以下代码:
// Services used by identity
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddCookie(IdentityConstants.ApplicationScheme, o =>
{
o.LoginPath = new PathString("/Account/Login");
o.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
};
})
/*...*/
这会将 Cookie 配置为默认设置。我试图将 Jwt 配置放在它后面,但无济于事。 cookie 保持默认实现。
但我仍然可以将 Bearer scheme 配置为默认授权策略:
builder.Services
.AddAuthorization(opt =>
{
// Configure the default policy
opt.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
});
这增加了一个全局策略,要求每个请求都通过这个策略。所以你不需要再在任何地方添加
[Authorize]
属性。只需在您的[AllowAnonymous]
上方放一个AuthController
,这样人们仍然可以注册。