You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7 Web API如何从AWS Cognito获取更多用户声明(如email)

实现自动从OIDC UserInfo端点获取额外声明的方案

你的需求完全可以实现,不需要手动编写独立的UserInfo调用逻辑,通过扩展JwtBearer的验证事件就能优雅完成。以下是具体步骤:

1. 核心思路

利用JwtBearerOptions的OnTokenValidated事件,在Token验证通过后,自动调用Cognito的UserInfo端点获取用户属性,并将这些属性添加到当前请求的ClaimsPrincipal中,后续接口就能直接读取这些声明。

2. 修改Program.cs配置

先注入IHttpClientFactory(用于复用HttpClient,避免Socket耗尽问题),再修改JwtBearer的配置,添加事件处理逻辑:

// 注入HttpClient工厂
builder.Services.AddHttpClient();

builder.Services
    .AddAuthentication(options => options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        builder.Configuration.GetSection("Auth:Cognito").Bind(options);
        
        // 配置Token验证完成后的事件
        options.Events = new JwtBearerEvents
        {
            OnTokenValidated = async context =>
            {
                // 获取HttpClient实例
                var httpClientFactory = context.HttpContext.RequestServices.GetRequiredService<IHttpClientFactory>();
                var httpClient = httpClientFactory.CreateClient();
                
                // 构造Cognito UserInfo端点地址
                var userInfoEndpoint = $"{options.Authority}/oauth2/userInfo";
                
                // 构造请求,携带当前验证通过的AccessToken
                var request = new HttpRequestMessage(HttpMethod.Get, userInfoEndpoint);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.SecurityToken.RawData);
                
                // 调用UserInfo端点
                var response = await httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();
                
                // 解析返回的用户属性
                var userInfo = await response.Content.ReadFromJsonAsync<Dictionary<string, object>>();
                
                // 将属性添加到当前用户的声明集合
                var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
                foreach (var kvp in userInfo)
                {
                    // 避免重复添加已存在的声明
                    if (!claimsIdentity.HasClaim(c => c.Type == kvp.Key))
                    {
                        claimsIdentity.AddClaim(new Claim(kvp.Key, kvp.Value.ToString()));
                    }
                }
            }
        };
    });

3. 关键注意事项

  • 确保AccessToken包含openid Scope:Cognito的UserInfo端点要求AccessToken必须携带openid权限,否则会返回403。需要在生成Token的客户端配置中添加该Scope。
  • 异常处理:生产环境中要添加对SendAsync失败的异常捕获(比如网络问题、Token过期),避免验证流程中断导致请求失败。
  • 声明去重:代码中已经处理了重复声明的问题,避免同一属性被多次添加。

4. 关于AddOpenIdConnect的说明

你提到的AddOpenIdConnect确实是为带有登录页面的Cookie认证场景设计的,它会处理完整的OIDC授权流程(跳转登录页、获取授权码、交换Token等),不适合纯REST API的Bearer Token验证模式,所以用JwtBearer的事件扩展是更适配的方案。

内容的提问来源于stack exchange,提问作者Rowan Freeman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:17:35