Home > Mobile >  Authenticate & Authorize User Before Hitting Actions
Authenticate & Authorize User Before Hitting Actions

Time:10-20

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:

ASP.NET Core security topics

  • Related