ABP Commercial (direct references) Volo.Abp.OpenIddict.Pro.* — 10.0.1 (e.g. EntityFrameworkCore, HttpApi, Application, Blazor., Domain.Shared, contracts). Volo.Abp.Account.Pro. — 10.0.1 (auth-server and Blazor packages such as Public.Web.OpenIddict, Admin., Public., Blazor server/WASM, HTTP API, etc.). Those versions are consistent across the projects that reference them (auth-server, identity service, administration service, Blazor).
Underlying OpenIddict (NuGet, transitive) After restore, apps/auth-server/PoweredByArray.AuthServer/obj/project.assets.json resolves the OpenIddict stack at 7.2.0, including packages such as OpenIddict.Core, OpenIddict.Abstractions, OpenIddict.Server, OpenIddict.Server.AspNetCore, OpenIddict.Validation, and related packages — all at 7.2.0.
So in short: ABP OpenIddict Pro / Account Pro = 10.0.1, and the OpenIddict libraries pulled in under that are 7.2.0.
- Exception message and full stack trace:
- Time out requests to requests that perform look-ups against the identity-service
- Steps to reproduce the issue:
- Enter a tenant
- Sign in with an external provider
- Prompts to register
- Register the user. (POST /Account/Register?isExternalLogin=True)
- Then the request times out & any other read operations on both (Identity and Auth Server) fail.
Restarting the (OpenIddict) Auth Server resolves the issue and we can continue normally. This is not sustainable in a production account.
2 Answer(s)
-
0
Hi,
We reproduced this. The cause is in
Volo.Abp.Account.Pro.Public.Web/Pages/Account/Register.cshtml.cs:OnPostAsyncis wrapped in[UnitOfWork], and insideRegisterExternalUserAsyncit awaitshttpClient.GetStreamAsync(picture)to download the external provider's profile picture. The defaultHttpClienthas no timeout, so when the picture URL is slow or unreachable (e.g.https://graph.microsoft.com/v1.0/me/photo/$valuereturning 404 or being blocked by your network), the transaction stays open with theAbpUsersX lock held, and every other read on that table is blocked. In the MicroService template the AuthServer also connects directly to the identity database, so the lock affects both services. Restarting AuthServer kills the connection, the transaction rolls back, and the lock is released — that's why a restart "fixes" it.Note: just lowering
HttpClient.Timeoutis not a full fix. The lock is still held until the HTTP call completes or times out, so the window only shrinks from ~100s to N seconds; concurrent reads are still blocked for N seconds on every external registration.Workaround
Stop mapping the
pictureclaim in your AuthServer module'sConfigureExternalProvidersso the download path is skipped. Remove the picture-relatedClaimActionsfor each external provider you use:.AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, options => { // remove this line: // options.ClaimActions.MapCustomJson("picture", _ => "https://graph.microsoft.com/v1.0/me/photo/$value"); options.SaveTokens = true; }) .AddGoogle(GoogleDefaults.AuthenticationScheme, options => { // remove this line: // options.ClaimActions.MapJsonKey(AbpClaimTypes.Picture, "picture"); }) .AddTwitter(TwitterDefaults.AuthenticationScheme, options => { // remove this line: // options.ClaimActions.MapJsonKey(AbpClaimTypes.Picture, "profile_image_url_https"); options.RetrieveUserDetails = true; });With the
pictureclaim no longer set,RegisterExternalUserAsyncskips the HTTP download entirely (theif (!picture.IsNullOrWhiteSpace())branch is not entered), so the UoW transaction commits immediately after theINSERT AbpUsersand the lock is released. AuthServer no longer needs to be restarted.Trade-off: new external users won't have their avatar auto-imported from the provider; they can upload one later from the profile page.
We'll address this properly in an upcoming release by moving the picture download outside the UoW transaction so the avatar import keeps working without holding the lock.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
Quick update: the framework fix we'll ship is simpler than what I described earlier. Instead of moving the picture download out of the unit of work, we just bound the outbound HTTP call with a short timeout. The default
HttpClient.Timeoutis 100 seconds, which is why the lock could be held that long — capping it to 5 seconds is enough to make theAbpUsersrow lock release on its own, so AuthServer no longer needs to be restarted.The patch adds a configurable option:
public class AbpAccountOptions { // ... public TimeSpan ExternalProfilePictureDownloadTimeout { get; set; } = TimeSpan.FromSeconds(5); }And
RegisterExternalUserAsyncapplies it to theHttpClientbeforeGetStreamAsync. Profile pictures from external providers are normally tens of KB and finish in well under a second, so 5s leaves plenty of headroom for slow networks while preventing the lock from being held long enough to matter.If you want to apply the same fix locally before the next release, two options:
Keep your current workaround (removing the
pictureClaimActionsmapping) — still valid and avoids the call entirely. Trade-off: no avatar auto-import.If you want to keep importing the avatar, override
RegisterModel.RegisterExternalUserAsyncin your ownMyRegisterModel : RegisterModeland copy the original method, adding one line right afterHttpClientFactory.CreateClient():
var httpClient = HttpClientFactory.CreateClient(); httpClient.Timeout = TimeSpan.FromSeconds(5); // add this lineThat alone makes the lock window predictable. With this in place, even when the external picture URL is slow or unreachable, the transaction commits within 5 seconds and the table is unlocked — no restart required.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)