Open Closed

Refresh token mechanism in Blazor Server #7955


User avatar
0
neethucp created

Hi,

We are getting unauthorized message in the application when the token expires. Can you please help on how to implement refresh token mechanism so that the user is not redirected to login page before saving the changes.

  • ABP Framework version: v8.2.3
  • UI Type: Blazor Server
  • Database System: EF Core (SQL Server) /
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes

4 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    After check , no meaning to implement it, because you have to refresh current page to use the refresh token to get new access token.

  • User Avatar
    0
    neethucp created

    Hi,

    We have this issue raised by the customer that they are getting "Unauthorized" message while they are in the middle of updating some forms and they are forced to reload the page without saving the updates they made. That is the reason that we are looking for a refresh token mechanism so that they don't get the unauthorized messages while they are actively using the application.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi

    Sorry, there is no ASPNETCore official support at this time https://github.com/dotnet/aspnetcore/issues/55213

    I'll try to find a temporary solution and let you know.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can try this

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IAbpAccessTokenProvider))]
    public class MyAccessTokenProvider : HttpContextAbpAccessTokenProvider
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IConfiguration _configuration;
        
        public MyAccessTokenProvider(IHttpContextAccessor httpContextAccessor, IHttpClientFactory httpClientFactory, IConfiguration configuration) : base(httpContextAccessor)
        {
            _httpClientFactory = httpClientFactory;
            _configuration = configuration;
        }
    
        public override async Task<string?> GetTokenAsync()
        {
            var authenticationInfo = await HttpContextAccessor.HttpContext.AuthenticateAsync();
            
            var refreshToken = authenticationInfo.Properties?.GetTokenValue("refresh_token");
            var tokenString = authenticationInfo.Properties?.GetTokenValue("access_token");
            
            if (tokenString.IsNullOrWhiteSpace() || refreshToken.IsNullOrWhiteSpace())
            {
                return tokenString;
            }
    
            var token = new JwtSecurityTokenHandler().ReadJwtToken(tokenString);
            
            // check token expiration and refresh token if needed
            if (token.ValidTo < DateTime.UtcNow.AddMinutes(5))
            {
                var client = _httpClientFactory.CreateClient();
                
                var response = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
                {
                    ClientId = _configuration["AuthServer:ClientId"]!,
                    ClientSecret = _configuration["AuthServer:ClientSecret"]!,
                    RefreshToken = refreshToken,
                    Address = _configuration["AuthServer:Authority"]!.EnsureEndsWith('/') + "connect/token"
                });
                           
                
                authenticationInfo.Properties.UpdateTokenValue(
                    "access_token", response.AccessToken);
                authenticationInfo.Properties.UpdateTokenValue(
                    "refresh_token", response.RefreshToken);
    
                return response.AccessToken;
            }
            
            return tokenString;
            
        }
    }
    
Made with ❤️ on ABP v9.1.0-preview. Updated on December 10, 2024, 06:38