Skip to content

.NET library to allowing a client application get new access tokens

License

Notifications You must be signed in to change notification settings

brunobrandes/jwt-refresh-token

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jwt Refresh Token

.NET library to allowing a client application get new access tokens

Introduction

Jwt Refresh Token is .Net library to provide a importante authentication aspects, and using Jwt Token (learn more jwt.io web site) and Refresh Token.

Refresh Token basically require a unique token identifier to obtain additional access tokens. Access token arent'n valid for an long period for security and Refresh Token strategy can help to re-authentication a user without login credential 🤔 (some scratches risks here)

Architecture

This project is based in Onion Architecture created by Jeffrey Palermo in 2008.

Flow

Miro

Supported Databases

Goal of this project is support at last 3 main Azure Databases:

Cosmos DB

To install Jwt.Refresh.Token.Cosmos (include prereleases), run the following command in the .NET CLI

dotnet add package Jwt.Refresh.Token.Cosmos --prerelease
Usage
  1. ✯ Cosmos setup

The first step to do is provision your cosmos db, or if you already have it, create the token container id (choose name you want) with partitionKey '/userId'.

Implement IUserRepository for get user by id and password. UserId

  1. ✯ Configure settings app:
"JwtRefreshTokenDescriptor": {
    "AlgorithmKey": "YOUR_ALGORITHM_KEY",
    "Issuer": "https://your-resource.com",
    "Audience": "https://your-resource.com"
  },
  "JwtRefreshTokenExpires": {
    "CreateMilliseconds": 60000,
    "RefreshMilliseconds": 900000
  },
  "JwtRefreshTokenCosmos": {
    "ConnectionString": "YOUR_COSMOS_CONNECTIONSTRING",
    "DatabaseId": "YOUR_DATABASEID",
    "TokenContainerId": "YOUR_TOKEN_CONTAINERID"
  }
  1. ✯ Configure startup app:

Install ASP.NET Core authentication middleware

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

and configuring it in your application’s startup class file:

// [required] Add jwt domain services
builder.Services.AddJwtRefreshTokenServices(builder.Configuration);

// [required (cosmos)]  Add jwt cosmos repositories
builder.Services.AddJwtRefreshTokenCosmosServices(builder.Configuration);

// [optional]  Bind util token expires config
builder.Services.BindJwtRefreshTokenExpiresOptions(builder.Configuration);

// [required] AspNetCore Authentication config
builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
    // choose your bearer config 
    .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = true;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
              .GetBytes(builder.Configuration.GetValue<string>("JwtRefreshTokenDescriptor:AlgorithmKey"))),
            ValidateIssuer = true,
            ValidateAudience = true
        };
    });

// [required] AspNetCore Authentication config
builder.Services
    .AddAuthorization(auth =>
    {
        auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
            .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser().Build());
    });
  1. ✯ Create token controller

Creating token controler to management token:

[ApiController]
[Route("[controller]")]
public class TokenController : ControllerBase
{
    private readonly ILogger<TokenController> _logger;
    private readonly ITokenAppService _tokenAppService;
    private readonly IOptionsSnapshot<JwtRefreshTokenExpiresOptions> _jwtRefreshTokenExpiresOptions;

    public TokenController(ILogger<TokenController> logger, 
        ITokenAppService tokenAppService,
        IOptionsSnapshot<JwtRefreshTokenExpiresOptions> jwtRefreshTokenExpiresOptions)
    {
        _logger = logger;
        _tokenAppService = tokenAppService;
        _jwtRefreshTokenExpiresOptions = jwtRefreshTokenExpiresOptions;
    }

    private string GetRemoteIpAddress()
    {
        return this.Request?.HttpContext?.Connection?
            .RemoteIpAddress?.ToString();
    }

    [HttpPost("")]
    public async Task<IActionResult> PostAsync([FromForm] string userId, 
      [FromForm] string password, CancellationToken cancellationToken)
    {
        var token = await _tokenAppService.CreateAsync(userId, 
            password, _jwtRefreshTokenExpiresOptions.Value.CreateMilliseconds,
            GetRemoteIpAddress(), cancellationToken);

        return new TokenResult(token);
    }

    [Authorize("Bearer")]
    [HttpPatch("")]
    public async Task<IActionResult> RefreshAsync([FromForm] string tokenId,
      [FromForm] string userId, CancellationToken cancellationToken)
    {
        var token = await _tokenAppService.RefreshAsync(tokenId, 
            userId, _jwtRefreshTokenExpiresOptions.Value.RefreshMilliseconds,
            GetRemoteIpAddress(), cancellationToken);

        return new TokenResult(token);
    }

    [Authorize("Bearer")]
    [HttpPatch("/revoke")]
    public async Task<IActionResult> RevokeAsync([FromForm] string tokenId,
      [FromForm] string userId, CancellationToken cancellationToken)
    {
        var updated = await _tokenAppService.TryRevokeAsync(tokenId, 
            userId, GetRemoteIpAddress(), cancellationToken);

        return Ok(new { updated = updated });
    }
}

See integration test api here

TODO

  • Incrise unit test coverage
  • Create pipeline
  • Implement PostgreeSql infrastructure
  • Implement Sql Databse infrastructure

About

.NET library to allowing a client application get new access tokens

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages