这是我在过去一年中遇到的最困难的代码,"在.NET Web API应用程序中验证来自AWS Cognito的JWT令牌"。 AWS文档仍然有许多需要改进之处。
以下是我在新的.NET 6 Web API解决方案中使用的(因此Startup.cs现在包含在Program.cs中。如有需要,请进行调整以适应您的.NET版本。与.NET 5和更早版本的主要区别在于通过名为 builder
的变量访问 Services
对象,因此每当您看到像 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 here}",
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未经授权的响应。 StackOverflow上的其他人说他们不得不这样做才能使OAuth的身份验证/身份验证代码授权类型起作用。显然,对于隐式授权,
ValidateAudience = true
也可以正常工作,但是隐式授权被大多数人视为已弃用,如果可能,您应该尝试避免使用它。
还要注意,我正在设置
options.MetadataAddress
。根据另一个StackOverflow用户的说法,这显然允许AWS在必要时从后台缓存签名密钥,而AWS定期更换这些密钥。
一些官方的AWS文档(嘘)误导了我,让我使用了
builder.Services.AddCognitoIdentity();
(.NET 5及更早版本使用
services.AddCognitoIdentity();
)。显然,这是用于“ASP.NET”应用程序的情况,其中后端提供前端(例如Razor / Blazor)。或者它已经过时了,谁知道呢。这在AWS的网站上,因此它很可能已被弃用...
至于控制器,仅在类级别添加一个简单的
[Authorize]
属性就足够了。不需要在
[Authorize]
属性中指定“Bearer”作为
AuthenticationScheme
,也不需要创建中间件。
如果您想跳过在每个控制器上添加另一个
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.UseAuthorization()
之前使用 app.UseAuthentication
。
以下是 Program.cs/Startup.cs 中的 using
:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.IdentityModel.Tokens;
JsonConvert.DeserializeObject<JsonWebKeySet>(json)
可能无法正常工作 - 请改用此方法:new JsonWebKeySet(json)
。 - YS.options.MetadataAddress =" https://cognito-idp.<region>.amazonaws.com/<pool>/.well-known/openid-configuration"
- Michael Petito