Open Closed

Users having ""Unauthorized" error message after upgraded to framework 7.2.0 #5310


User avatar
0
scottie.tang@cpy.com.hk created
  • ABP Framework version: v7.2.0
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

Hi, after we recently upgrade our project's ABP framework from 5.X to 7.2.0. We found that some users are having "Unauthorized" error message when they are accessing some of my functions, the only temporary solution/workaround is to logout and login again. (We just guess that the users maybe carrying some expired/invalid tokens in their browser.)

  1. Do you have any advises on how to solve this issue?
  2. Could we force user to logout when unauthorized access is detected? If yes, any way to do it ? ( force user to logout )

Thanks.


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

    Hi,

    Will this problem occur if you create a new project of 7.2.0?

    The information you have provided is not enough for me to find the problem, if you can share a project that can reproduce the problem, I will check it. shiwei.liang@volosoft.com

  • User Avatar
    0
    scottie.tang@cpy.com.hk created

    Hi.

    This problem is not occured if I create a new project of 7.2.0.

    Our project is upgraded from 5.X to 7.2.0. After upgrade, some of our users receive "Unauthorized" message. The only thing they can do is click "OK" and re-login.

    Before the upgrade, it appears that some users did not log out of their accounts. As a result, we suspect that their tokens were carried over to the new version and might have become invalid after the upgrade.

    Could this issue be related to the upgrade from IdentityServer to OpenIdDict? Or other issues? Please kindly advise, thanks!

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Before the upgrade, it appears that some users did not log out of their accounts. As a result, we suspect that their tokens were carried over to the new version and might have become invalid after the upgrade.

    Of course, The previous token is no longer valid after changing the Auth provider

    Could you share the auth server logs?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    I see two clients here: iAE_Web and iAE_BlazorServerTiered, there must be a problem.

    BTW, could you share the ConfigureAuthentication method code?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can try to send a request and force logout.

    public static class MyAuthenticationOptionsExtensions
    {
         public static CookieAuthenticationOptions MyIntrospectAccessToken(this CookieAuthenticationOptions options, string oidcAuthenticationScheme = "oidc")
            {
                options.Events.OnValidatePrincipal = async principalContext =>
                {
                    if (principalContext.Principal == null || principalContext.Principal.Identity == null || !principalContext.Principal.Identity.IsAuthenticated)
                    {
                        return;
                    }
        
                    var logger = principalContext.HttpContext.RequestServices.GetRequiredService<ILogger<CookieAuthenticationOptions>>();
        
                    var accessToken = principalContext.Properties.GetTokenValue("access_token");
                    if (!accessToken.IsNullOrWhiteSpace())
                    {
                        var openIdConnectOptions = await GetOpenIdConnectOptions(principalContext, oidcAuthenticationScheme);
                        var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
                        {
                            Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
                            ClientId = openIdConnectOptions.ClientId,
                            ClientSecret = openIdConnectOptions.ClientSecret,
                            Token = accessToken
                        });
        
                        if (response.IsError)
                        {
                            logger.LogError(response.Error);
                            await SignOutAsync(principalContext);
                            return;
                        }
        
                        if (!response.IsActive)
                        {
                            logger.LogError("The access_token is not active.");
                            await SignOutAsync(principalContext);
                            return;
                        }
        
                        logger.LogInformation("The access_token is active.");
                    }
                    else
                    {
                        logger.LogError("The access_token is not found in the cookie properties, Please make sure SaveTokens of OpenIdConnectOptions is set as true.");
                        await SignOutAsync(principalContext);
                    }
    
    
                    var service = principalContext.HttpContext.RequestServices.GetRequiredService<IxxxService>();
    
                    try
                    {
                        await service.xxxxx().....
                    }
                    catch (AbpRemoteCallException e)
                    {
                        if (e.Message.Contains("Unauthorized"))
                        {
                            await SignOutAsync(principalContext);
                        }
                    }
    
                };
        
                return options;
            }
        
            private async static Task<OpenIdConnectOptions> GetOpenIdConnectOptions(CookieValidatePrincipalContext principalContext, string oidcAuthenticationScheme)
            {
                var openIdConnectOptions = principalContext.HttpContext.RequestServices.GetRequiredService<IOptionsMonitor<OpenIdConnectOptions>>().Get(oidcAuthenticationScheme);
                if (openIdConnectOptions.Configuration == null && openIdConnectOptions.ConfigurationManager != null)
                {
                    openIdConnectOptions.Configuration = await openIdConnectOptions.ConfigurationManager.GetConfigurationAsync(principalContext.HttpContext.RequestAborted);
                }
        
                return openIdConnectOptions;
            }
        
            private async static Task SignOutAsync(CookieValidatePrincipalContext principalContext)
            {
                principalContext.RejectPrincipal();
                await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
            }
    }
    
    context.Services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies", options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromDays(365);
        options.MyIntrospectAccessToken();
    })
    .......
    

    After a while all users have logged in with OpenIddict, you should be able to remove this method `

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11