Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple authentication methods in asp.Net core 2.2

Is there a way to use JWT bearer authentication AND a custom authentication method in .net core? I want all actions to default to JWT, except in a few cases where I want to use a custom authentication header.

like image 896
David Derman Avatar asked Oct 12 '25 05:10

David Derman


1 Answers

I finally figured out how to do it. This example uses JWT authentication by default and custom authentication in certain rare cases. Please note, from what I've read, Microsoft seems to discourage writing your own auth. Please use at your own risk.

First, add this code to the startup.cs ConfigureServices method to ensure that authentication gets applied globally.

services.AddMvc(options => 
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    })

Then, add this to configure the schemes you wish to use (in our case JWT and Custom).

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    // Jwt Authentication
    .AddJwtBearer(options =>
    {
        options.Audience = ".......";
        options.Authority = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_...";
    })
    // Custom auth
    .AddScheme<CustomAuthOptions, 
        CustomAuthHandler>(CustomAuthOptions.DefaultScheme, options => { });

Next create a class to hold your custom authentication options:

public class CustomAuthOptions : AuthenticationSchemeOptions
{
    public const string Scheme = "custom auth";
    public const string CustomAuthType = "custom auth type";
}

Finally, add an authentication handler to implement the custom authentication logic.

public class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
    public CustomAuthHandler(
        IOptionsMonitor<CustomAuthOptions> options, 
        ILoggerFactory logger, 
        UrlEncoder encoder, 
        ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // Auth logic goes here
        if (!Request.Headers....) 
        {
            return Task.FromResult(AuthenticateResult.Fail("Authentication Failed."));
        }

        // Create authenticated user
        ClaimsPrincipal principal = .... ;

        List<ClaimsIdentity> identities = 
            new List<ClaimsIdentity> {
                new ClaimsIdentity(CustomAuthOptions.CustomAuthType)};

        AuthenticationTicket ticket = 
            new AuthenticationTicket(
                new ClaimsPrincipal(identities), CustomAuthOptions.Scheme);

        return Task.FromResult(AuthenticateResult.Success(ticket));
    }
}

Finally, to tie it all together, add an authorize attribute to the actions you wish to use custom authorization on.

[HttpGet]
[Authorize(AuthenticationSchemes = CustomAuthOptions.Scheme)]
public HttpResponseMessage Get()
{
    ....
}

Now JWT authentication will automatically get applied to all actions, and custom authentication will get added to only the actions with the Authorize attribute set to the custom scheme.

I hope this helps someone.

like image 117
David Derman Avatar answered Oct 16 '25 05:10

David Derman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!