【问题标题】:generate role-based claims for aws cognito id token为 aws cognito id 令牌生成基于角色的声明
【发布时间】: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")]有什么办法吗?

【问题讨论】:

    标签: amazon-web-services asp.net-core-webapi amazon-cognito role-based-access-control


    【解决方案1】:

    使用IClaimsTransformation 将cognito 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"
            };
            ...
        });
    

    【讨论】:

    • 不错的一个..谢谢
    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 2018-08-10
    • 2020-08-15
    • 2013-08-19
    • 2015-04-09
    • 1970-01-01
    • 2021-04-10
    • 2020-02-13
    相关资源
    最近更新 更多