xavier
xavier

Reputation: 2039

AddAuthentication + RequireAuthenticatedUser = redundant?

I use Azure Active Directory to authenticate my users:

services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => this.Configuration.Bind("AzureAd", options));

I've seen here, in subsection "Authorization for specific endpoints", that RequireAuthenticatedUser should be added:

services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
    builder => builder.RequireAuthenticatedUser()));

However, isn't it already performed in the previous step?

I wonder if this second check could be useful to perform some other kind of customized checks. For example: to access my application I need a user to be authenticated using AzureAD and also they should be included in my Users table. Can I use this "second authentication" to perform this check?

Upvotes: 2

Views: 897

Answers (1)

Marcus Höglund
Marcus Höglund

Reputation: 16846

The authentication will try to figure out who you are, it will not break if it cant. But if you try to reach an endpoint, which will require an authenticated user, it will tell you that it can't authenticate you (401). So to answer your question, the first step will figure out who you are and the second step will tell where you need to be authenticated in your system.

If you want to add more requirements to the policy you can create your own custom requirements and add that to the policy.

Here's an example:

services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
    builder => builder.RequireAuthenticatedUser().AddRequirements(new CustomUserRequirement())));

Add the CustomUserRequirement and CustomUserPolicyRequirementHandler to handle the requirement

public class CustomUserPolicyRequirementHandler : AuthorizationHandler<CustomUserRequirement>
{
    private readonly IUserService _userService;

    public MeetingsPolicyRequirementHandler(
        IUserService userService)
    {
        _userService = userService;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomUserRequirement requirement)
    {
        if (!context.HasFailed)
        {
            if (_userService.DoesUserExistInMyCustomTable(context.User))
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
        }
        return Task.CompletedTask;
    }
}

public class CustomUserRequirement : IAuthorizationRequirement { }

Then register the CustomUserRequirement handler on your service provider

services.AddTransient<IAuthorizationHandler, CustomUserPolicyRequirementHandler>();

Upvotes: 4

Related Questions