根据我的研究,最好将 API 和 IdentityServer 分成 2 个项目(也是 2 个域,即:https://api.mywebsite.com 和 https://identity.mywebsite.com ), 所以我这样做了。
在我的 IdentityServer/AuthenticationController.cs @ login-method 中,它目前正在制作一个 JWT 令牌,其中包含声明列表(角色、名称、Jti(idk 是什么)、电子邮件等,并将其放入JwtSecurityToken.
我的 WebAPI/ProductController.cs 中的 [Authorize(Roles = "Admin")] 如何与我的 IdentityServer 通信然后授权它。是否在“AddAuthentication(...);”中在 Program.cs 服务中?或者在 AddJwtBearer(...) 中?或者专门在 ValidIssuer 中?
API(即https://api.mywebsite.com)和IdentityServer(https://identityserver.mywebsite.com)之间的连接在哪里?
我的IdentityServer-项目Program.cs:
...
builder.Services.AddIdentityServer().AddAspNetIdentity<IdentityUser>().AddClientStore<InMemoryClientStore>().AddResourceStore<InMemoryResourcesStore>();
builder.Services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidAudiences = builder.Configuration.GetSection("JWT:ValidAudiences").Get<string[]>(),
ValidIssuer = builder.Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWT:Secret"]))
};
});
...
我的 API 项目 Program.cs:
...
builder.Services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidAudiences = builder.Configuration.GetSection("JWT:ValidAudiences").Get<string[]>(),
ValidIssuer = builder.Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWT:Secret"]))
};
});
...
另外,当涉及到 IdentityServer 和 API 身份验证和授权时,我的两个代码块是否编写得很好?
API中的AddJwtBearer负责获取传入的访问令牌并将其转换为“ClaimsPrincipal”用户。然后将该用户及其所有声明传递给授权处理程序,该处理程序将确定是否允许该用户通过。
例如 [Authorize(Roles = "Admin")] 属性将检查用户中的角色声明是否包含 Admin 角色声明。
通常不需要在 AddJwtBearer 中指定 IssuerSigningKey,而是让 AddJwtBearer 在启动时直接从 IdentityServer 中自动获取它。 (只需删除 IssuerSigningKey)。如果 API 无法与 IdentityServer 通信,您通常会添加 IssuerSigningKey。
为了补充这个答案,我写了一篇博客文章,详细介绍了这个主题: 解决 ASP.NET Core 中的 JwtBearer 身份验证问题