我正在将旧版 ASP.NET MVC 应用程序移植到 .NET Core,我还尝试替换现有的身份框架以使用由应用程序负载均衡器处理的 AWS Cognito 用户池。
当请求到达 ALB 且未经授权的用户被重定向到 Cognito 托管的登录页面时,他们可以登录,我已经完成了大部分设置和工作。这一切都正常,但我想将 JWT 中的信息(从 ALB 传回)连接到 ASP.NET Identity 框架,以便我可以访问填充的“User”对象。
包含 JWT 的响应头 header 也是非标准的“X-Amzn-Oidc-Data”,而不是标准授权中的。我已经考虑过使用 Microsoft.AspNetCore.Authentication.JwtBearer 但我相信这需要标准的授权 header 。
我确实遇到过这个项目https://github.com/awslabs/aws-alb-identity-aspnetcore这似乎正是我需要的东西,但它似乎已被放弃。有没有人在实现相同目标方面有类似的经验可以分享?
更新:这是我们根据 Mickaël 的评论更新的启动代码:
services.AddAuthentication("Cognito")
.AddJwtBearer("Cognito", options =>
{
options.Events = options.Events ?? new JwtBearerEvents();
options.Events.OnMessageReceived = context =>
{
string amazonOidcDataHeader = context.Request.Headers["X-Amzn-Oidc-Data"];
if (!string.IsNullOrEmpty(amazonOidcDataHeader))
{
context.Token = amazonOidcDataHeader.Trim();
}
return Task.CompletedTask;
};
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 = this.Configuration["Authentication:Cognito:ValidIssuer"],
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = this.Configuration["Authentication:Cognito:ClientId"],
ValidateAudience = true
};
});
现在从 header 中检索 token 并将其推送到 context.Token 属性中,Identity User 对象仍然不包含任何声明。
最佳答案
内置 JWT 提供程序具有可扩展点,可以通过 JwtBearerEvents.OnMessageReceived
事件从几乎任何地方获取 token 。
你可以这样做:
services
.AddAuthentication("Cognito")
.AddJwtBearer("Cognito", options =>
{
options.Events ??= new JwtBearerEvents();
options.Events.OnMessageReceived = context =>
{
const string bearerPrefix = "Bearer ";
string amazonOidcDataHeader = context.Request.Headers["X-Amzn-Oidc-Data"];
if (!string.IsNullOrEmpty(amazonOidcDataHeader) && amazonOidcDataHeader.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase))
{
context.Token = amazonOidcDataHeader.Substring(bearerPrefix.Length).Trim();
}
return Task.CompletedTask;
};
});
作为引用,请参阅 GitHub 上的这段代码摘录,其中显示了处理程序的实现,以及它如何使用在 MessageReceived
事件期间分配的 token (如果有),或尝试提取该 token 来自标准 Authorization
header ,否则: https://github.com/dotnet/aspnetcore/blob/20f5f6fbc3db4a66faeb941e56db6ace333c1817/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs#L58-L91
关于c# - 在 ALB 上使用 Cognito 用户池进行 ASP.NET Core 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65602986/