I'm looking for an "easy" way to automatically add role claims to the local user in order to test my authorization logic; that is, wanting to add some specific claims to the local user before they are authorized by my controllers.
I've learned that in the past something akin to this could be done for the controllers:
#if DEBUG
protected override void OnAuthorization(AuthorizationContext filterContext)
{
var roles = new[] { "role-under-test"};
HttpContext.User = new GenericPrincipal(new GenericIdentity("DebugUser"), roles);
base.OnAuthorization(filterContext);
}
#endif
Yet that was prior to .NET Core which is what I'm working in now. Slowly I've worked my way to the code presented below, which seems to work, but is clearly much more of a hassle compared to the above example. So my question is whether anyone knows a better--more easy--way to achieve this?
The custom authorization attribute:
public class CustomAuthAttribute : RolesAuthorizationRequirement {
public CustomAuthAttribute(IEnumerable<string> allowedRoles) : base(allowedRoles) { }
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement) {
#if DEBUG
context.User.AddIdentity(new ClaimsIdentity(new GenericIdentity("DebugUser"), new[] {
new Claim(ClaimsIdentity.DefaultRoleClaimType, "users"),
new Claim(ClaimsIdentity.DefaultRoleClaimType, "admins")
}));
#endif
return base.HandleRequirementAsync(context, requirement);
}
}
In Startup.cs
public void ConfigureServices(IServiceCollection services) {
// ...
services.AddAuthorization( options =>
options.AddPolicy("UsersAndAdmins",
policy => policy.AddRequirements(new CustomAuthAttribute(new []{"users", "admins"}))));
}
And then using it in the controllers:
[Authorize(Policy = "UsersAndAdmins")]
public class HomeController : Controller {
// ...
You want claims transformation;
Write a claims transformation that looks like
public class ClaimsTransformer : IClaimsTransformer
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
((ClaimsIdentity)context.principal.Identity).AddClaim(new Claim("Admin", "true"));
return Task.FromResult(principal);
}
}
And wire it up inside Configure
in startup.cs
app.UseClaimsTransformation(new ClaimsTransformationOptions
{
Transformer = new ClaimsTransformer()
});
Of course if it's for test you'd wrap it inside an environment check to ensure you're in your dev environment :)