Open Closed

10.6.1: identity session never saved when the client disconnects after /connect/token (related to #10853) #10957


User avatar
0
matic.rek@infotim.com created

This looks like the issue in #10853, which you answered as fixed by [PR #26017](https://github.com/abpframework/abp/pull/26017). We see it on 10.6.1, with one addition: when the client closes the connection right after reading the token response, the session is not just saved late, it is never saved.

Environment

  • ABP 10.6.1 (commercial), Blazor Server app with the built-in auth server (AbpAccountPublicWebOpenIddictModule, Volo.Abp.Account.Pro.Public.Web.OpenIddict 10.6.1)
  • .NET 10, IIS 10 in-process hosting, EF Core with SQL Server, multi-tenancy on, IsDynamicClaimsEnabled = true
  • Standard middleware order: UseAuthentication → UseAbpOpenIddictValidation → UseMultiTenancy → UseUnitOfWork → UseDynamicClaims → UseAuthorization → … → UseConfiguredEndpoints
  • Client: Android app using the password grant (/connect/token), then Bearer calls to [Authorize] application services. It closes the connection as soon as it has read the token response, which is normal for mobile HTTP clients.

Problem

The first API call after a successful login fails with 401 and WWW-Authenticate: ... error_description="SessionExpired". /connect/token returned 200 and AbpSecurityLogs has LoginSucceeded, but AbpSessions has no row for the token’s session_id (and OpenIddictTokens has no row either). Every later call with that token fails the same way.

Reproduction

We reproduced it with a small script that logs in with the password grant and then calls an [Authorize] endpoint with the token, on a new connection each time. Results on the same server and database:

  1. Login connection closed right after reading the token, then the endpoint is checked every 100 ms for 10 s: never succeeds. 5 of 5 rounds, 101 checks each, all SessionExpired. No AbpSessions row is ever created.

  2. Login connection kept open, then the endpoint is checked every 10 ms: the first checks are rejected with SessionExpired. A check 35–50 ms after the token response passes, with the same token. 5 of 5 rounds:

    | Round | Last rejected check (ms after token) | First passing check (ms after token) | | ----- | ------------------------------------ | ------------------------------------ | | 1 | – | 25 | | 2 | 32 | 50 | | 3 | 21 | 46 | | 4 | 22 | 36 | | 5 | 26 | 44 |

  3. SQL after a mixed run of 15 logins: only the 5 logins whose connection stayed open have an AbpSessions row. The 10 that closed the connection have LoginSucceeded in AbpSecurityLogs but no session. So the token is sent before the session is saved. If the client disconnects in that window, the session is never saved.

Our reading of the cause

  • The session is created by OpenIddictCreateIdentitySession (a ProcessSignInContext handler) through IdentitySessionManager.CreateAsync. That runs while the SignIn result executes, after the token controller’s unit-of-work action filter has finished. The insert therefore stays in the request-wide unit of work reserved by AbpUnitOfWorkMiddleware.
  • AbpUnitOfWorkMiddleware completes that unit of work after await next(context), which is after OpenIddict has written the token response. It passes ICancellationTokenProvider.Token, i.e. HttpContext.RequestAborted.
  • When the client closes the connection after reading the response, RequestAborted fires, the commit is cancelled and the session (and token entry) are rolled back. The security log survives because it is saved in its own unit of work.
  • OpenIddictValidateIdentitySessionValidationHandler / IdentitySessionChecker then rejects every request with that token as SessionExpired.

Workarounds

  • Client side: keep the login connection open about 2 s before closing it. This works, but every client has to know about it.

  • Server side, tested with the same script (5 rounds per variant):

    | | No change | ICancellationTokenProvider.Use(CancellationToken.None) around /connect/token, before UseUnitOfWork() | /connect/token in AbpAspNetCoreUnitOfWorkOptions.IgnoredUrls | | --- | --------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | | Connection closed, then polled | session never saved | saved 0–41 ms after the token | there at the first check | | Connection kept open, then polled | saved 20–64 ms after the token | saved 6–92 ms after the token | there at the first check | | Call right after the token | 15 of 15 rejected | 13 of 15 rejected | 30 of 30 accepted (two runs) |

    The cancellation override stops the session from being lost, but it is still saved after the token. IgnoredUrls saves it before the token is sent and fixes both. We use IgnoredUrls until we can upgrade to a release with the fix.

Question

In which ABP release is the fix from #10853 (PR #26017) included? Is it in a 10.6.x patch, or only in 10.7 or later?

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

1 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • The fix referenced in #10853 (implemented by PR #26017) was not released in 10.6.1.

    • Based on the available verified information, it was scheduled for “an upcoming release” at the time of the #10853 answer, but the exact version (e.g., 10.6.2/10.6.3 vs 10.7.0+) is not explicitly stated in any verified source I can access here.

    • Since you can still reproduce “session never saved when the client disconnects” on 10.6.1, the safe/confirmed conclusion is: it is not included in 10.6.1; the earliest version containing it cannot be definitively confirmed from verified sources in this environment.

    • Practically: if you need a deterministic server-side behavior today, your current mitigation of adding /connect/token to AbpAspNetCoreUnitOfWorkOptions.IgnoredUrls (or equivalent “commit-before-flush” approach) is consistent with the framework-side fix described in #10853, and you should keep it until you upgrade to a version where you can confirm the fix is present by testing.

    Links (validated):

    • https://abp.io/support/questions/10853
    • https://github.com/abpframework/abp/pull/26017

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on November 02, 2026, 06:56
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.