Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generate role-based claims for aws cognito id token

Authenticate with AWS Cognito, I can get ID token including cognito:groups { admin, user}. From ASPNetCore Webapi, I can authorize using Policy (folows AWS tutorial 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")
                ));
        });            

It works when declaring Policy in my Controller [Authorize(Policy = "admin")]. However my api uses roles instead.

Any way to do with [Authorize(Role = "admin")] please?

like image 512
beewest Avatar asked Sep 20 '25 13:09

beewest


1 Answers

Transform cognito group into claim role using 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);
        }
    }

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

The token is generated by cognito username and password:

[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    ;
        }
like image 60
beewest Avatar answered Sep 23 '25 03:09

beewest