为 aws cognito id 令牌生成基于角色的声明

Posted

技术标签:

【中文标题】为 aws cognito id 令牌生成基于角色的声明【英文标题】:generate role-based claims for aws cognito id token 【发布时间】:2020-03-19 05:35:25 【问题描述】:

使用 AWS Cognito 进行身份验证,我可以获得包括cognito:groups admin, user 在内的 ID 令牌。 从 ASPNetCore Webapi,我可以使用 Policy 进行授权(遵循 AWS 教程 https://www.youtube.com/watch?v=M6qTrI7kmZk):

services.AddSingleton<IAuthorizationHandler, CognitoGroupAuthorizationHandler>();
        services.AddAuthorization(options=> 
            options.AddPolicy("admin", p => p.Requirements.Add(
                new CognitoGroupAuthorizationRequirement("admin")
                ));
            options.AddPolicy("user", p => p.Requirements.Add(
                new CognitoGroupAuthorizationRequirement("user")
                ));
        );            

在我的控制器[Authorize(Policy = "admin")] 中声明策略时有效。但是我的 api 使用了角色。

请问[Authorize(Role = "admin")]有什么办法吗?

【问题讨论】:

【参考方案1】:

使用IClaimsTransformationcognito group 转换为claim role

public class ClaimsTransformer : IClaimsTransformation
    
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        
            var claims = new List<Claim>();

            var cognitoClaims = principal.Claims.Where(t => t.Type == "cognito:groups").ToList();
            foreach (var claim in cognitoClaims)
            
                var claim2 = new Claim(ClaimTypes.Role, claim.Value);
                claims.Add(claim2);
            

            var claimsIdentity = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);

            return new ClaimsPrincipal(claimsIdentity);
        
    

注册Startup\ConfigureServices:

public void ConfigureServices(IServiceCollection services)
        

            // Adds Amazon Cognito as Identity Provider
            //services.AddCognitoIdentity();

            services.AddAuthentication("Bearer")
            .AddJwtBearer(options =>
            
                options.Audience = "aws-app-client-id";
                options.Authority = "https://cognito-idp.us-east-1.amazonaws.com/aws-pool-id";
            );

            services.AddScoped<IClaimsTransformation, ClaimsTransformer>();

            services.AddControllers();
        

token由cognito用户名和密码生成:

[HttpGet]
        [Route("username/password")]
        public async Task<string> Get(string username, string password)
        
            var provider = new AmazonCognitoIdentityProviderClient(RegionEndpoint.USEast1);

            var pool = new CognitoUserPool(poolId, clientId, provider);

            var user = new CognitoUser(userId, clientId, pool, provider);

            var request = new InitiateSrpAuthRequest
            
                Password="cognito-password"
            ;

            AuthFlowResponse response = await user.StartWithSrpAuthAsync(request);


            return response.AuthenticationResult.IdToken    ;
        

【讨论】:

对此的快速警告,ClaimsTransformer 将删除存在的任何其他声明。【参考方案2】:

一个简单的解决方案(至少在 .NET 5 中)是在 services.AddJwtBearer TokenValidationParameters 选项中设置 RoleClaimType 属性。

services
    .AddAuthentication(options => 
    
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    )
    .AddJwtBearer(options =>
    
        options.TokenValidationParameters = new TokenValidationParameters 
         
            ValidateAudience = false,
            RoleClaimType = "cognito:groups"
        ;
        ...
    );

【讨论】:

不错的一个..谢谢

以上是关于为 aws cognito id 令牌生成基于角色的声明的主要内容,如果未能解决你的问题,请参考以下文章

aws cognito用户获取id令牌android

如何配置 AWS 用户 cognito 身份验证流程以在 Java sdk 后端生成身份令牌、访问令牌?

通过 Cognito 生成的授权令牌识别 AWS Lambda 中的用户

AWS Cognito:生成令牌并在使用 amazon-cognito-identity-js SDK 刷新后

ASP.NET Core AWS Cognito JWT

AWS Cognito:将自定义声明/属性添加到 JWT 访问令牌