DEV Community

Dominic Pascasio
Dominic Pascasio

Posted on • Edited on

ASP.NET Core - Write a Simple JWT Authentication

This is just a simple implementation of JWT authentication to get you started.

  1. Add the package Microsoft.AspNetCore.Authentication.JwtBearer
  2. You need a secret key, store it using user-secrets:

    dotnet user-secrets init
    dotnet user-secrets set "Authentication:JwtSecret" "thisismysecret"
    

    Warning! User secret feature is not intended to be used in production.

  3. In your Program.cs or Startup.cs:

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc.Authorization;
    using Microsoft.IdentityModel.Tokens;
    using System.Text;
    

    Add the service:

    builder.Services
        .AddAuthentication()
        .AddJwtBearer("JwtScheme", options => {
            options.TokenValidationParameters = new TokenValidationParameters 
            {
                ValidIssuer = "https://localhost:<port>",
                ValidAudience = "https://localhost:<port>",
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,                
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Authentication:JwtSecret"])),
            };
    }) 
    

    Tell MVC that users should be authenticated and with JWTScheme.

    builder.Services.AddControllers(options => {
        options.Filters.Add(new AuthorizeFilter
            (new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes("JwtScheme")
                .Build()));
    })
    

    Alternatively, you can use Authorize attribute for each controller or endpoint, specifying the scheme(s) to be allowed:

    [Authorize(AuthenticationSchemes = "JwtScheme")]
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase { ... }
    

    In the HTTP Request pipeline, add before mapping controllers:

    app.UseAuthentication();
    app.UseAuthorization();
    
  4. In your authentication controller:

    using Microsoft.IdentityModel.Tokens;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Text;
    .
    .
    //inject `IConfiguration` to `_configuration` in the constructor.
    

    In your login method, add [AllowAnonymous] attribute. Then:

    //validate credentials and get user details here
    var key = Encoding.ASCII.GetBytes(_configuration["Authentication:JwtSecret"]);
    var claims = new List<Claim>
        {
            new Claim("sub", user.Id),
            new Claim("name", user.FullName)
        };
    var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Issuer = "https://localhost:<port>",
            Audience = "https://localhost:<port>",
            Expires = DateTime.UtcNow.AddDays(7),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
    
        };
    
    var tokenHandler = new JwtSecurityTokenHandler();
    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
    

    The login method will return the token generated.

  5. In your client's HTTP request, add the Authorize header with the value Bearer <the token generated>. You can test it via Postman or any testing program you prefer.

Resource
auth0 - Claims
Infoworld Article - JWT
Microsoft Docs - User Secrets

Top comments (0)