3

使用 AWS Cognito 进行身份验证,我可以获得包括cognito:groups { admin, user}. 从 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")
                ));
        });            

它在我的 Controller 中声明 Policy 时有效[Authorize(Policy = "admin")]。但是我的 api 使用了角色。

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

4

2 回答 2

3

转换cognito groupclaim role使用IClaimsTransformation

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();
        }

令牌由 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    ;
        }
于 2019-12-25T06:12:16.273 回答
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"
        };
        ...
    });
于 2021-05-13T16:21:59.657 回答