这很容易成为我去年不得不使用的最困难的代码。“在 .NET Web API 应用程序中验证来自 AWS Cognito 的 JWT 令牌”。AWS 文档仍有很多不足之处。
这是我用于新的.NET 6 Web API 解决方案的内容(因此 Startup.cs 现在包含在 Program.cs 中。如果需要,请调整以适合您的 .NET 版本。与 .NET 5 及更早版本的主要区别是Services
对象被访问通过一个名为 的变量builder
,因此无论何时您看到类似 的代码services.SomeMethod...
,您都可以将其替换builder.Services.SomeMethod...
为使其与 .NET 6 兼容):
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = "https://cognito-idp.{aws region here}.amazonaws.com/{Cognito UserPoolId}",
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = "{Cognito AppClientId here}",
ValidateAudience = false
};
options.MetadataAddress = "https://cognito-idp.{aws region here}.amazonaws.com/{Cognito UserPoolId here}/.well-known/openid-configuration";
});
请注意,我已ValidateAudience
设置为false
. 否则,我会从 .NET 应用程序收到 401 Unauthorized 响应。SO上的其他人说他们必须这样做才能使OAuth的身份验证/身份验证代码授权类型起作用。显然ValidateAudience = true
,对于隐式授权来说,效果很好。为什么你在 2022 年使用隐式授权呢?
另请注意,我正在设置options.MetadataAddress
. 对于另一位 SO 用户来说,这显然允许在幕后缓存来自 AWS 的签名密钥,这些密钥会不时轮换。
我被一些让我使用的官方 AWS 文档 (boo) 误入歧途builder.Services.AddCognitoIdentity();
(services.AddCognitoIdentity();
对于 .NET 5 及更早版本)。显然,这适用于后端为前端提供服务的“ASP.NET”应用程序(例如 Razor/Blazor)。或者它可能已被弃用,谁知道呢。它在 AWS 的网站上,所以很可能会被弃用......
至于控制器,[Authorize]
类级别的简单属性就足够了。无需AuthenticationScheme
在[Authorize]
属性中指定“Bearer”,也无需创建中间件。
如果您想跳过必须using
向每个控制器以及[Authorize]
属性添加另一个,并且希望每个控制器中的每个端点都需要 JWT,您可以将其放在 Startup/Program.cs 中:
builder.Services.AddControllers(opt =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
opt.Filters.Add(new AuthorizeFilter(policy));
});
确保 Program.cs(.NET 5 及更早版本的 Startup.cs)app.UseAuthentication
中的app.UseAuthorization()
.
以下是using
Program.cs/Startup.cs 中的 s:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.IdentityModel.Tokens;