Check the docs before asking a question: https://abp.io/docs/latest Check the samples to see the basic tasks: https://abp.io/docs/latest/samples The exact solution to your question may have been answered before, and please first use the search on the homepage.
Provide us with the following info:
🧐 Hint: If you are using the ABP Studio, you can see all the information about your solution from the configuration window, which opens when you right-click on the solution and click on the Solution Configuration button.
With ABP Identity Session Management enabled together with Dynamic Claims, the OAuth password grant endpoint /connect/token can return 200 with a valid access_token (JWT signature/expiry are OK), but the immediately following API request fails with:
error=invalid_tokenerror_description=SessionExpiredThe failure happens because ABP cannot find the token’s session_id in the AbpSessions table at request time (IdentitySessionChecker log: "Could not find SessionId(...) in the database."). In our observations, the row may appear in AbpSessions shortly after, which suggests a commit/visibility timing issue rather than an invalid JWT.
After /connect/token returns 200, any immediately subsequent API request using the new access token should pass Identity Session validation when Dynamic Claims is enabled.
POST /connect/token (password grant) returns 200 and returns access_token / refresh_token.SessionExpired due to IdentitySessionChecker not finding the session_id in AbpSessions.session_id row exists later.Representative log text: "Could not find SessionId(<sid>) in the database." "The token is no longer valid because the user's session expired."
During the same /connect/token HTTP request:
OpenIddictCreateIdentitySession inserts the Identity Session row into AbpSessions.AbpSessions row becomes visible) occurs later in the ASP.NET request pipeline.As a result, the next HTTP request can start and validate session_id before the inserted row is committed/visible under the DB isolation level.
In some environments, reverse proxies/dev proxies may amplify the issue when the connection is closed after response flush, leading to an aborted request pipeline.
Environment conditions we observed:
IsDynamicClaimsEnabled = true)/connect/tokenWe found ABP Support issue #10850: https://abp.io/support/questions/10850/1050-regression-identity-session-invalid-after-second-re-authentication-in-same-browser-session--IdentitySessionChecker-cannot-find-just-created-SessionId-user-force-logged-out
That report focuses on regression after second re-authentication (sign-out + sign-in) and session revocation behavior in a browser session. Our case occurs right after a successful /connect/token response with an immediate next API call, without relying on the same “second re-auth” flow.
In our integration, we implemented a mitigation by replacing the default OpenIddict Identity Session handler with a wrapper that commits the Identity Session earlier.
Behavior:
OpenIddictServerEvents.ProcessSignIn, we execute the official OpenIddictCreateIdentitySession inside a new transactional UnitOfWork (requiresNew: true, isTransactional: true).CompleteAsync(CancellationToken.None) immediately after the official handler runs, before OpenIddict writes the token response to the client.public class OpenIddictCommitIdentitySessionHandler : IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>
{
public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor
.CreateBuilder<OpenIddictServerEvents.ProcessSignInContext>()
.UseScopedHandler<OpenIddictCommitIdentitySessionHandler>()
.SetOrder(100000)
.SetType(OpenIddictServerHandlerType.Custom)
.Build();
private readonly OpenIddictCreateIdentitySession _createIdentitySession;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public OpenIddictCommitIdentitySessionHandler(
OpenIddictCreateIdentitySession createIdentitySession,
IUnitOfWorkManager unitOfWorkManager)
{
_createIdentitySession = createIdentitySession;
_unitOfWorkManager = unitOfWorkManager;
}
public async ValueTask HandleAsync(OpenIddictServerEvents.ProcessSignInContext context)
{
using var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
await _createIdentitySession.HandleAsync(context);
await uow.CompleteAsync(CancellationToken.None);
}
}
Result:
/connect/token still returns 200 normally, but the immediate next API calls no longer fail with SessionExpired.10.5.0