I'm using simple cookie authentication (.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie
) and require an authenticated user by default so use:
options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
This works fine: as expected navigating to a URL when not authenticated redirects to my login page.
I've now added the custom AuthorizationHandler
below that works with the users role.
This also works, however it seems to override the default cookie authentication behaviour, i.e. If I am not logged in & navigate to a controller decorated with my handler [Authorize(Policy = "DemoPolicy")]
then rather than being redirected to the login page my HandleRequirementAsync()
is invoked (and currently fails as context.User
is null
).
Is there a way for these things to play together? Can I change my AuthorizationHandler
so that it recognises that there is no authenticated user & redirects to my login page?
AuthorizationHandler:
public class RoleHandler : AuthorizationHandler<RolesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesRequirement requirement) {
string userRoleName = context.User.Claims.FirstOrDefault(claim => claim.Type == ClaimsIdentity.DefaultRoleClaimType).Value;
if (userRoleName == "let-me-in")
context.Succeed(requirement);
}
That uses a simple requirement
public class RolesRequirement : IAuthorizationRequirement
{
public RolesRequirement(string role) {
Role = role;
}
public string Role { get; }
}
I create a policy:
services.AddAuthorization(options => {
options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.AddPolicy(SecuriyPolicies.RequireManagerRole, policy => policy.Requirements.Add(new RolesRequirement("let-me-in")));
});
And apply it to a controller:
[Authorize(Policy = "DemoPolicy")]
public class MyController : Controller {
...