Search code examples
authenticationjwtopenid-connectasp.net-core-3.1hotchocolate

Specifying an authentication scheme for a single route that's handled by middleware


I have a new ASP.Net Core 3 MVC site that I've added GraphQL to with HotChocolate. I have users signing in to the MVC side using cookie-based auth with Auth0:

services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        })
    .AddCookie()
    .AddOpenIdConnect("Auth0", options =>
        {
            ...
        });

But for GraphQL requests, I need JWT auth, for which I'd use:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(config =>
        {
            ...
        });

They both independently work fine. Cookie auth allows controller use; JWT auth allows GQL use. But I can't figure out how to get the cookie auth for the controllers and JWT for the /graphql route.

A little context: HotChocolate uses a custom middleware to handle requests that come in to the /graphql route. It's not on a controller, so I can't just specify the scheme with the Authorize attribute as there isn't a controller to put it on.

Similar questions

(There were a few others, mainly focused on combining REST and MVC, but these both go to controllers so the scenario is a bit different.)


Solution

  • I had the same issue, so I thought I post my solution in case others may have the same problem.

    Hot Chocolate uses the Default Authentication Scheme so in Startup I declare JWT as the default:

        services.AddAuthentication(options =>
        {
            options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    
        })
    

    And everywhere I need Cookie Authentication I simply add:

    [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]