I want to authenticate & authorize users before hitting actions. In each of my controllers' actions, there are duplicated lines of code in each of them.
Is there a method so that I will be able to authenticate & authorize users in ControllerBase
?
For example, I want to have a CustomControllerBase
to put authentication & authorization logic there:
public class CustomBaseController : ControllerBase {
// authentication & authorization logic
}
Then controllers inherit from CustomBaseController
public class FooController : CustomBaseController {
}
Here is how do I authorize a user:
var userItem = dbService.GetAuthorizedUser(User) // ClaimsPrincipal
if (userItem == null) return Unauthorized(ResponseMessage.UnAuthorized);
The first 2 lines of code are run in each action.
CodePudding user response:
I would suggest to use ASP.NET (Core) built-in security features.
Authorize only authenticated user, unless specified differently on controller or action with global fallback policy.
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
Enable authentication and authorization middleware.
app.UseAuthentication();
app.UseAuthorization();
Create authorization requirements with desired logic.
public class DefaultAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement>
{
private IDbService _dbService;
public DefaultAuthorizationHandler(IDbService dbService)
{
_dbService = dbService;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement)
{
// We skip as user is not authenticated. Nothing to authorize
if (context.User == null)
{
return Task.CompletedTask;
}
//
var userItem = _dbService.GetAuthorizedUser(context.User);
if (userItem != null)
{
context.Succeed(requirement);
}
// in some cases you want to have strict requirement
// to force used to be denied even if other requirements are met.
// context.Fail();
return Task.CompletedTask;
}
}
Register authorization handler to DI.
builder.Services.AddScoped<IAuthorizationHandler, DefaultAuthorizationHandler>();
Make login endpoint to allow anonymous users by overriding fallback policy.
[AllowAnonymous]
public class LoginController
{
...
}
Related resources: