为 aws cognito id 令牌生成基于角色的声明
generate role-based claims for aws cognito id token
使用 AWS Cognito 进行身份验证,我可以获得包括 cognito:groups { admin, user}
在内的 ID 令牌。
从 ASPNetCore Webapi,我可以使用策略授权(遵循 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")]
吗?
使用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();
}
令牌由 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 ;
}
一个简单的解决方案(至少在 .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 进行身份验证,我可以获得包括 cognito:groups { admin, user}
在内的 ID 令牌。
从 ASPNetCore Webapi,我可以使用策略授权(遵循 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")]
吗?
使用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();
}
令牌由 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 ;
}
一个简单的解决方案(至少在 .NET 5 中)是在 services.AddJwtBearer TokenValidationParameters 选项中设置 RoleClaimType 属性。
services
.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
RoleClaimType = "cognito:groups"
};
...
});