Authentication

Authentication determines a user's identity. It is a prerequisite for authorization and also lets you access the authenticated user in your resolvers, for example to build a me field that returns the current user's profile.

Hot Chocolate integrates with the ASP.NET Core authentication system, so you can reuse existing authentication configuration and any supported authentication provider.

Learn more about authentication in ASP.NET Core

Setup

Setting up authentication follows the same pattern as any ASP.NET Core application. The example below uses JWT bearer tokens, but you can substitute any authentication scheme that ASP.NET Core supports.

1. Install the JWT Bearer Package

Bash
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Warning
All HotChocolate.* packages need to have the same version.

2. Register the Authentication Scheme

C#
// Program.cs
var signingKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes("MySuperSecretKey"));
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = "https://auth.chillicream.com",
ValidAudience = "https://graphql.chillicream.com",
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey
};
});

This is an example configuration. Use a proper key management solution for production.

3. Add Authentication Middleware

Register the authentication middleware in the request pipeline:

C#
// Program.cs
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQL();
});

4. Install the Hot Chocolate Authorization Package

Bash
dotnet add package HotChocolate.AspNetCore.Authorization
Warning
All HotChocolate.* packages need to have the same version.

5. Register Authorization on the Schema

C#
// Program.cs
builder
.AddGraphQL()
.AddAuthorization()
.AddQueryType<Query>();

Calling AddAuthorization() on the IRequestExecutorBuilder registers the @authorize directive and makes the authenticated user's identity available to resolvers. It does not lock out unauthenticated users. To restrict access, use authorization.

Accessing the ClaimsPrincipal

After authentication, the ClaimsPrincipal of the current user is available in your resolvers.

C#
// Types/UserQueries.cs
[QueryType]
public static partial class UserQueries
{
public static User? GetMe(ClaimsPrincipal claimsPrincipal, UserService users)
{
var userId = claimsPrincipal.FindFirstValue(ClaimTypes.NameIdentifier);
if (userId is null)
{
return null;
}
return users.GetById(userId);
}
}

Use ClaimsPrincipal to read claims such as the user ID, email, or roles:

C#
var userId = claimsPrincipal.FindFirstValue(ClaimTypes.NameIdentifier);
var email = claimsPrincipal.FindFirstValue(ClaimTypes.Email);
var isAdmin = claimsPrincipal.IsInRole("Administrator");

Modifying the ClaimsPrincipal

If you need to add claims or identities to the ClaimsPrincipal before it reaches your resolvers, register an IHttpRequestInterceptor:

C#
// Interceptors/HttpRequestInterceptor.cs
public class HttpRequestInterceptor : DefaultHttpRequestInterceptor
{
public override ValueTask OnCreateAsync(
HttpContext context,
IRequestExecutor requestExecutor,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken)
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Country, "us"));
context.User.AddIdentity(identity);
return base.OnCreateAsync(context, requestExecutor, requestBuilder, cancellationToken);
}
}
C#
// Program.cs
builder
.AddGraphQL()
.AddHttpRequestInterceptor<HttpRequestInterceptor>();

Learn more about interceptors

Next Steps

Last updated on April 13, 2026 by Michael Staib