【问题标题】:ASP.NET Core authentication using Cognito User Pools on the ALB在 ALB 上使用 Cognito 用户池进行 ASP.NET Core 身份验证
【发布时间】:2021-04-12 15:00:36
【问题描述】:

我正在将一个旧的 ASP.NET MVC 应用程序移植到 .NET Core,我也在尝试替换现有的身份框架以使用由应用程序负载均衡器处理的 AWS Cognito 用户池。

当请求到达 ALB 并且未经授权的用户被重定向到他们可以登录的 Cognito 托管登录页面时,我已经完成了大部分设置和工作。这一切正常,但我想将 JWT 中的信息(从 ALB 传回)连接到 ASP.NET 身份框架,以便我可以访问填充的“用户”对象。

包含 JWT 的响应标头标头也是非标准的“X-Amzn-Oidc-Data”,而不是在标准授权中。我看过使用 Microsoft.AspNetCore.Authentication.JwtBearer 但我相信这需要标准的授权标头。

我确实遇到了这个项目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
                    };
                });

现在从标头中检索令牌并将其推送到 context.Token 属性中,身份用户对象仍然不包含任何声明。

【问题讨论】:

    标签: c# amazon-web-services asp.net-core amazon-cognito


    【解决方案1】:

    内置的 JWT 提供程序有一个扩展点,可以通过 JwtBearerEvents.OnMessageReceived 事件从几乎任何地方获取令牌。

    你可以这样做:

    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 事件期间分配的令牌(如果有的话),或者尝试从标准 @987654325 中提取令牌@标头否则:https://github.com/dotnet/aspnetcore/blob/20f5f6fbc3db4a66faeb941e56db6ace333c1817/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs#L58-L91

    【讨论】:

    • 谢谢,这真的很有帮助。我是否认为这应该从 JWT 填充 Identity User 对象?
    • 完全没问题。是的,除了令牌来源之外的其他所有内容都将相同,包括填充 HttpContext.User 属性。
    • 我的 HttpContext.User 仍然是空的,我一定是遗漏了一些东西,我需要设置中间件的另一部分吗?
    • 将日志记录级别提高到调试并分析 HTTP 请求的条目。如果没有完整的代码,即Startup 类,就不可能知道可能缺少什么。
    猜你喜欢
    • 2021-04-08
    • 2018-02-23
    • 2018-09-03
    • 2021-06-23
    • 2016-08-18
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    相关资源
    最近更新 更多