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?
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 ;
}