Skip to content

Commit

Permalink
Add refresh token when sending
Browse files Browse the repository at this point in the history
  • Loading branch information
oveldman committed Mar 23, 2024
1 parent 7f2b16f commit fcaca14
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using MadWorldNL.Clients.Admin.Domain;
using MadWorldNL.Clients.Admin.Domain.Authentications;
using MadWorldNL.Clients.Admin.Services.Authentications;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
Expand All @@ -20,8 +20,8 @@ public AuthenticationManager(
_authenticationStateProvider = (JwtAuthenticationStateProvider)authenticationStateProvider;
_localStorage = localStorage;
}

public async Task<AuthenticationToken> LoginFromSessionAsync()
public async Task<AuthenticationToken> GetCurrentAuthenticationTokenAsync()
{
var storageResult = await _localStorage.GetAsync<AuthenticationToken>(AuthenticationToken.Entry);

Expand All @@ -30,9 +30,19 @@ public async Task<AuthenticationToken> LoginFromSessionAsync()
return new AuthenticationToken();
}

_authenticationStateProvider.Authenticate(storageResult.Value.AccessToken);
return storageResult.Value;
}

public async Task<AuthenticationToken> LoginFromSessionAsync()
{
var token = await GetCurrentAuthenticationTokenAsync();

if (token.IsSuccess)
{
_authenticationStateProvider.Authenticate(token.AccessToken);
}

return token;
}

public async Task<AuthenticationToken> LoginAsync(string username, string password)
Expand All @@ -44,9 +54,7 @@ public async Task<AuthenticationToken> LoginAsync(string username, string passwo
return token;
}

await _localStorage.SetAsync(AuthenticationToken.Entry, token);
_authenticationStateProvider.Authenticate(token.AccessToken);

await AuthenticateAsync(token);
return token;
}

Expand All @@ -55,4 +63,31 @@ public async Task LogoutAsync()
_authenticationStateProvider.Logout();
await _localStorage.DeleteAsync(AuthenticationToken.Entry);
}

public async Task<AuthenticationToken> RefreshTokenAsync()
{
var token = await GetCurrentAuthenticationTokenAsync();

if (!token.IsSuccess)
{
return token;
}

token = _authenticationService.RefreshToken(token.RefreshToken);

if (!token.IsSuccess)
{
await LogoutAsync();
return token;
}

await AuthenticateAsync(token);
return token;
}

private async Task AuthenticateAsync(AuthenticationToken token)
{
await _localStorage.SetAsync(AuthenticationToken.Entry, token);
_authenticationStateProvider.Authenticate(token.AccessToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using MadWorldNL.Clients.Admin.Domain.Authentications;

namespace MadWorldNL.Clients.Admin.Application.Authentications;

public class GrpcHttpMessageHandler : DelegatingHandler
{
private readonly IAuthenticationManager _authenticationManager;

public GrpcHttpMessageHandler(IAuthenticationManager authenticationManager)
{
_authenticationManager = authenticationManager;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = await GetJwtTokenAsync();
request.Headers.Add("Authorization", $"Bearer {token}");

return await base.SendAsync(request, cancellationToken);
}

protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
{
return SendAsync(request, cancellationToken).GetAwaiter().GetResult();
}

private async Task<string> GetJwtTokenAsync()
{
var authenticationToken = await _authenticationManager.GetCurrentAuthenticationTokenAsync();

if (!authenticationToken.IsSuccess)
{
throw new AuthenticationTokenException();
}

if (authenticationToken.Expires >= DateTime.UtcNow.AddMinutes(5))
{
return authenticationToken.AccessToken;
}

authenticationToken = await _authenticationManager.RefreshTokenAsync();

if (!authenticationToken.IsSuccess)
{
throw new AuthenticationTokenException();
}

return authenticationToken.AccessToken;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using MadWorldNL.Clients.Admin.Domain;
using MadWorldNL.Clients.Admin.Domain.Authentications;

namespace MadWorldNL.Clients.Admin.Application.Authentications;

public interface IAuthenticationManager
{
Task<AuthenticationToken> GetCurrentAuthenticationTokenAsync();
Task<AuthenticationToken> LoginFromSessionAsync();
Task<AuthenticationToken> LoginAsync(string username, string password);

Task LogoutAsync();
Task<AuthenticationToken> RefreshTokenAsync();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace MadWorldNL.Clients.Admin.Domain;
namespace MadWorldNL.Clients.Admin.Domain.Authentications;

public class AuthenticationToken
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace MadWorldNL.Clients.Admin.Domain.Authentications;

public class AuthenticationTokenException : Exception
{

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MadWorldNL.Clients.Admin.Application.Authentications;
using MadWorldNL.Clients.Admin.Services.Authentications;
using Microsoft.AspNetCore.Components.Authorization;
using Server.Presentation.Grpc.Account.V1;
using Server.Presentation.Grpc.Authentication.V1;

namespace MadWorldNL.Clients.Admin.Extensions;
Expand All @@ -9,10 +10,17 @@ public static class WebApplicationBuilderExtensions
{
public static void AddGrpcClients(this WebApplicationBuilder builder)
{
builder.Services.AddScoped<GrpcHttpMessageHandler>();

builder.Services.AddGrpcClient<Authentication.AuthenticationClient>(o =>
{
o.Address = new Uri(builder.Configuration["Identity:Host"]!);
});

builder.Services.AddGrpcClient<Account.AccountClient>(o =>
{
o.Address = new Uri(builder.Configuration["Identity:Host"]!);
}).AddHttpMessageHandler<GrpcHttpMessageHandler>();
}

public static void AddAdminServices(this WebApplicationBuilder builder)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using MadWorldNL.Clients.Admin.Domain;
using MadWorldNL.Clients.Admin.Domain.Authentications;
using Server.Presentation.Grpc.Authentication.V1;

namespace MadWorldNL.Clients.Admin.Services.Authentications;
Expand Down Expand Up @@ -31,4 +31,22 @@ public AuthenticationToken Login(string username, string password, string audien
Expires = response.Expiration.ToDateTime()
};
}

public AuthenticationToken RefreshToken(string refreshToken)
{
var request = new TokenRefreshRequest()
{
RefreshToken = refreshToken
};

var response = _client.TokenRefresh(request);

return new AuthenticationToken()
{
IsSuccess = response.IsSuccess,
AccessToken = response.AccessToken,
RefreshToken = response.RefreshToken,
Expires = response.Expiration.ToDateTime()
};
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using MadWorldNL.Clients.Admin.Domain;
using MadWorldNL.Clients.Admin.Domain.Authentications;

namespace MadWorldNL.Clients.Admin.Services.Authentications;

public interface IAuthenticationService
{
AuthenticationToken Login(string username, string password, string audience);
AuthenticationToken RefreshToken(string refreshToken);
}
2 changes: 2 additions & 0 deletions sources/Server.Presentation.Grpc/Services/AccountService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Grpc.Core;
using MadWorldNL.Server.Application.Users;
using MadWorldNL.Server.Presentation.Grpc.Mappers.Authentication;
using Microsoft.AspNetCore.Authorization;
using Server.Presentation.Grpc.Account.V1;

namespace MadWorldNL.Server.Presentation.Grpc.Services;

[Authorize]
public class AccountService : Account.AccountBase
{
private readonly ILogger<AccountService> _logger;
Expand Down

0 comments on commit fcaca14

Please sign in to comment.