Base solution for your next web application
Open Closed

Giriş yapan kullanıcının çıkış yaparken hata alması. #12608


User avatar
0
MarturAbpUser created

Merhabalar,

ASP.Net Zero (.Net Core 9 and Angular 19) uygulamasını Angular arayüzüyle birlikte kullanıyoruz. Uygulamada şöyle bir problemimiz var ve bu durum yeni oluştu.

Kullanıcı girişi olmasına (kullanıcı giriş yaptıktan sonra ekleme, silme, düzenleme gibi işlemler yapıyor) ragmen çıkış yapılamıyor ve ekte fotoğrafları yer alan hatayı veriyor (Bkz resim : Console Hata mesaj ve Dashboard Hata). Kendimiz debug yaptığımızda da kodun dll (AbpSessionExtensions.cs) kısmında “session.UserId.HasValue” kısmının true olduğunu görmemize rağmen kod false gibi hareket edip exception fırlatıyor. **(Belki debug bizi yanıltıyor da olabilir. Ancak fotoğrafta da görülebileceği gibi **“ToUserIdentifier methodunda session.UserId.HasValue değeri true ve kod bu şekilde GetUserId” methoduna geçiyor)

Defalarca cache sildik ve farklı tarayıcılarda (Chrome,Opera ve Edge) da denedik ancak 3 kullanıcıyız ve durum hepimizde aynı. LogOut kısmında da hiçbir çalışma yapmadık.

Konu ile ilgili yardımınızı rica ederiz.

English version:

Hello,

We are using an ASP.Net Zero application (.NET Core 9 and Angular 19) together with the Angular UI. We are experiencing a problem in the application, and this issue has appeared recently.

Even though the user is logged in (after logging in, the user can perform actions such as create, delete, and update), logout does not work and the error shown in the attached screenshots occurs (see images: Console Error Message and Dashboard Error).

When we debug the issue ourselves, we see that in the DLL code (AbpSessionExtensions.cs), the value of session.UserId.HasValue is true, but the code behaves as if it were false and throws an exception. (It is possible that debugging is misleading us; however, as can be seen in the screenshot, in the ToUserIdentifier method, session.UserId.HasValue is true, and the code proceeds to the GetUserId method accordingly.)

We have cleared the cache multiple times and tried different browsers (Chrome, Opera, and Edge). There are three of us using the system, and the issue occurs for all of us. We also have not made any changes to the Logout functionality.

We kindly request your assistance regarding this issue.

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

6 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @MarturAbpUser

    After reviewing the screenshots and your explanation, I can see the situation clearly. I recommend checking the following points:

    Calling Logout Directly from the Browser Address Bar

    From the screenshot, I can see that the https://localhost:44301/api/TokenAuth/LogOut?d=... endpoint is being called directly from the browser’s address bar. When an endpoint is invoked this way:

    • The Authorization: Bearer {token} header is not sent
    • Since the LogOut endpoint is protected with [AbpAuthorize]
    • Receiving the Current user did not login to the application! error is expected behavior

    For this reason, the logout operation must be triggered through the Angular application (via the logout button in the UI).

    If the Error Occurs During Logout from the Angular UI

    If this error occurs while logging out from the Angular interface, I recommend the following checks:

    Authorization Header Verification

    • Open Browser DevTools → Network tab

    • Locate the LogOut request

    • Verify that the following header is present in the Request Headers:

    Authorization: Bearer

    
    **Logout Method in `app-auth.service.ts`**
    
    Ensure that the token is being added to the headers in the following code:
    
    ```ts
    // angular/src/app/shared/common/auth/app-auth.service.ts
    logout(reload?: boolean, returnUrl?: string): void {
      let customHeaders = {
          [abp.multiTenancy.tenantIdCookieName]: abp.multiTenancy.getTenantIdCookie(),
          Authorization: 'Bearer ' + abp.auth.getToken(),
      };
      // ...
    }
    

    Also verify that abp.auth.getToken() is not empty or null. If necessary, you can temporarily log it as follows:

    console.log('Token:', abp.auth.getToken());
    

    AllowOneConcurrentLoginPerUser Setting

    If AllowOneConcurrentLoginPerUser is enabled:

    • The same user may have logged in from another browser or device
    • The previous token may have been invalidated
    • This can lead to an authorization error during logout

    Recommended Troubleshooting Steps

    1. Check the token value in the browser console

    2. Verify the Authorization header of the LogOut request in the Network tab

    3. Inspect the token expiry time

    4. For temporary debugging purposes:

      • Remove the [AbpAuthorize] attribute from the LogOut method and test
      • (For debugging only; not recommended in production)

    After performing these checks, please share your findings so we can provide more precise guidance.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    MarturAbpUser created

    Hello,

    First of all, I used the logout method from the Angular UI, and the error message is coming from the UI.

    I tried all of your recommendations, but none of them worked. The token is present during login, and it is still present when I attempt to log out, as confirmed by logging it. This clearly indicates a backend-related issue. I also checked the user claims, and they are present.

    Also, I activated the EnableSensitiveDataLogging and it send to this message: The association between entities 'User' and 'UserToken' with the key value '{UserId: 2}' has been severed, but the relationship is either marked as required or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, configure the relationship to use cascade deletes.

    By the way, I analyzed the issue and observed that the access token is removed successfully. However, an exception is thrown when the system attempts to remove the refresh token. It appears that the problem is related to the refresh token.

    I will share the database records before the issue (Picture 1) and after the issue (Picture 2). As you can see, before the issue both token timestamps (days) are the same, whereas after the issue they are different.

    // Access token is removed, it's okay

    var tokenValidityKeyInClaims = User.Claims.First(c => c.Type == AppConsts.TokenValidityKey);
    await RemoveTokenAsync(tokenValidityKeyInClaims.Value);
    

    Afterwards, there is a refresh token but the RemoveTokenAsync is throwing to exception.

    // refreshTokenValidityKeyInClaims isn't null

    var refreshTokenValidityKeyInClaims = User.Claims.FirstOrDefault(c => c.Type == AppConsts.RefreshTokenValidityKey);
    if (refreshTokenValidityKeyInClaims != null)
    {
        await RemoveTokenAsync(refreshTokenValidityKeyInClaims.Value); // throwing the exception
    }
    

    Also, I have shared my analysis with you in the screenshots above.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @MarturAbpUser

    Thank you for the detailed analysis and for sharing your findings.

    We have carefully reviewed your explanation and attempted to reproduce the same behavior on our side using a clean, out of the box ASP.NET Zero project. Under the same conditions, we were not able to reproduce the exception during refresh token removal. Both access token and refresh token are removed successfully without triggering an EF Core relationship error.

    It is likely related to a project specific customization, such as:

    • A modification to the User–UserToken relationship
    • A change in cascade delete or required foreign key configuration
    • A custom override in token or logout logic

    To investigate further and provide a concrete solution, we would need to review the project where the issue occurs. If you can share a reproducible sample or grant access to the project, we can analyze it in detail and guide you more accurately.

    You can send your project details to [email protected] so we can review the issue in detail and provide more specific guidance. By reviewing your project directly, we will be able to respond more efficiently and provide you with a more specific and targeted solution without prolonging the process.

    Looking forward to your feedback.

    Thank you

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @MarturAbpUser

    The error you are encountering during the logout process is caused by the DeleteBehavior configuration in Entity Framework Core.

    Root Cause:

    In your OnModelCreating method, DeleteBehavior.Restrict is being applied to all foreign key relationships:

    foreach (var foreignKey in modelBuilder.Model
        .GetEntityTypes()
        .SelectMany(e => e.GetForeignKeys()))
    {
        foreignKey.DeleteBehavior = DeleteBehavior.Restrict;
    }
    

    This configuration also affects the ABP Framework identity tables (such as AbpUserTokens, AbpUserLogins, AbpUserRoles, etc.). However, during the logout process, ABP expects certain relationships particularly those involving UserToken to use Cascade delete behavior.

    Solution:

    You need to exclude ABP identity tables (tables with the AbpUser* and AbpRole* prefixes) from this restriction:

    // Cascade delete is required for ABP identity tables (User-UserToken, User-UserLogin, etc.)
    var abpIdentityTablePrefixes = new[] { "AbpUser", "AbpRole", "AbpUserTokens" };
    
    foreach (var foreignKey in modelBuilder.Model
      .GetEntityTypes()
      .SelectMany(e => e.GetForeignKeys()))
    {
        var principalEntityName = foreignKey.PrincipalEntityType.GetTableName();
        var dependentEntityName = foreignKey.DeclaringEntityType.GetTableName();
    
        var isAbpIdentityRelation = abpIdentityTablePrefixes.Any(prefix =>
            (principalEntityName != null && principalEntityName.StartsWith(prefix)) ||
            (dependentEntityName != null && dependentEntityName.StartsWith(prefix)));
    
        if (!isAbpIdentityRelation)
        {
            foreignKey.DeleteBehavior = DeleteBehavior.Restrict;
        }
    }
    

    With this change, Restrict behavior will continue to apply to your application-specific tables, while allowing the cascade delete operations required by the ABP Framework to function correctly.

    After applying this change, please create a new migration and update the database, then test the issue again. If the problem persists, feel free to contact us.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    MarturAbpUser created

    The issue has been resolved. Thank you for you support.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    You’re welcome. Glad to hear the issue has been resolved. If you need any further assistance, feel free to reach out.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)