.net core 如何使用.AddJwtBearer()在.NET核心Web API中验证AWS Cognito JWT
在我的.NET核心Web API中,我很难弄清楚如何验证AWS Cognito提供给客户端的JWT 我不仅无法确定Microsoft.IdentityModel.Tokens.TokenValidationParameters的变量应该是什么,而且一旦我最终确定了,我就不知道如何从.net core 如何使用.AddJwtBearer()在.NET核心Web API中验证AWS Cognito JWT,.net-core,jwt,amazon-cognito,asp.net-core-webapi,jwk,.net Core,Jwt,Amazon Cognito,Asp.net Core Webapi,Jwk,在我的.NET核心Web API中,我很难弄清楚如何验证AWS Cognito提供给客户端的JWT 我不仅无法确定Microsoft.IdentityModel.Tokens.TokenValidationParameters的变量应该是什么,而且一旦我最终确定了,我就不知道如何从检索JWT密钥集https://cognito-idp.{region}.amazonaws.com/{pool ID}/.well-known/jwks.json 最后,通过大量随机搜索和反复试验,我找到了一个(似乎
检索JWT密钥集https://cognito-idp.{region}.amazonaws.com/{pool ID}/.well-known/jwks.json
最后,通过大量随机搜索和反复试验,我找到了一个(似乎不是很有效的解决方案)解决方案。然而,我花了太多的时间做这件事。引用这一点,再加上AWS关于这个主题的文档严重缺乏,我决定发布这个问答,以帮助其他人在将来更容易地找到这个解决方案
如果有更好的方法,请有人告诉我,因为除了下面列出的答案之外,我还没有找到一种方法。答案主要在于正确定义
TokenValidationParameters。IssuerSigningKeyResolver
(参数等,见此处:)
这就是告诉.NETCore验证发送的JWT的依据。还必须告诉它在哪里可以找到钥匙列表。人们不一定要硬编码密钥集,因为它通常由AWS旋转
一种方法是从issueSigningKeyResolver
方法中的URL获取并序列化列表。整个.AddJwtBearer()
可能如下所示:
Startup.cs ConfigureServices()方法:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(parameters.ValidIssuer + "/.well-known/jwks.json");
// serialize the result
var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
// cast the result to be the type expected by IssuerSigningKeyResolver
return (IEnumerable<SecurityKey>)keys;
},
ValidIssuer = "https://cognito-idp.{region}.amazonaws.com/{pool ID}",
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = "{Cognito AppClientID}",
ValidateAudience = true
};
});
// get the current logged in user's info
Auth.currentSession().then((user) => {
fetch('https://localhost:5001/api/values',
{
method: 'GET',
headers: {
// get the user's JWT token given to it by AWS cognito
'Authorization': `Bearer ${user.signInUserSession.accessToken.jwtToken}`,
'Content-Type': 'application/json'
}
}
).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.error(e))
})
只有当您需要对验证进行更细粒度的控制时,才需要这里提供的答案 否则,下面的代码足以验证jwt
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "{yourAuthorizationServerAddress}";
options.Audience = "{yourAudience}";
});
Okta有一篇关于这方面的好文章
当JwtBearer中间件第一次处理请求时,它
尝试从授权服务器检索某些元数据(也包括
称为权威机构或发行人)。此元数据或发现文档
在OpenID Connect术语中,包含公钥和其他
验证令牌所需的详细信息。(想知道元数据是什么样子吗?下面是一个示例发现文档。)
如果JwtBearer中间件找到此元数据文档,则
自动配置自身。很漂亮
真棒的回答。客户端的Amplify已经做了一些更改,因此对于令牌,我们现在应该使用user.signInUserSession.accessToken.jwtToken:)与2021年(core 3.1)一样,
JsonConvert.DeserializeObject(json)
可能不起作用-改用这个:new JsonWebKeySet(json)
谢谢您的回答!当我在2018年做这件事时,我无法使用您描述的方法专门与AWS Cognito合作并进行放大。然而,我已经多次成功地将JWT与我自己的身份验证和用户管理实现结合使用。然而,如果这现在起作用,那是个好消息!这会处理关键点集的旋转吗?