question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

External Authentication does not work sometime when user does not exist

See original GitHub issue

I using ABP framework for my project. It is AspCore + Angular target Full .Net framework. I am using External Authentication for login. I have followed the steps mentioned in the document. I have configured it to use Windows Authentication which works fine when the user already exists in the DB. I noticed that when it is the first time that user is visiting the website it gently registers the user and then authenticates it into the system. For some reason sometimes when it is the first time that user is visiting the website it throws an error. After like 10-20 refresh it works fine sometimes. Interestingly when it finally goes in after several page refresh the user id jumps from the latest which (e.g. user id 6) to user id 10000 or from 10004 to 20000.

Here is the error in the log:

INFO 2018-05-15 11:19:54,995 [13 ] ore.Mvc.Internal.ControllerActionInvoker - Executing action method SAH.NEO.Controllers.TokenAuthController.Authenticate (SAH.NEO.Web.Core) with arguments (SAH.NEO.Models.TokenAuth.AuthenticateModel) - ModelState is Valid ERROR 2018-05-15 11:19:55,042 [9 ] Mvc.ExceptionHandling.AbpExceptionFilter - There is no such an entity. Entity type: SAH.NEO.Authorization.Users.User, id: 9 Abp.Domain.Entities.EntityNotFoundException: There is no such an entity. Entity type: SAH.NEO.Authorization.Users.User, id: 9 at Abp.Domain.Repositories.AbpRepositoryBase2.<GetAsync>d__21.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__51.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.Users.AbpUserStore2.<GetUserNameFromDatabaseAsync>d__88.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.Users.AbpUserManager2.d__47.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.AbpLogInManager3.<CreateLoginResultAsync>d__38.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Abp.Authorization.AbpLogInManager3.d__37.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.AbpLogInManager3.<LoginAsync>d__36.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__51.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException[TResult](Task1 task) at Nito.AsyncEx.AsyncContext.<>c__DisplayClass16_01.b__0(Task1 t) at System.Threading.Tasks.ContinuationResultTaskFromResultTask2.InnerInvoke() at System.Threading.Tasks.Task.Execute() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException[TResult](Task1 task) at Nito.AsyncEx.AsyncContext.Run[TResult](Func1 action) at Abp.Threading.AsyncHelper.RunSync[TResult](Func1 func) at Abp.Authorization.AbpLogInManagerExtensions.Login[TTenant,TRole,TUser](AbpLogInManager3 logInManager, String userNameOrEmailAddress, String plainPassword, String tenancyName, Boolean shouldLockout) at SAH.NEO.Controllers.TokenAuthController.GetLoginResult(String usernameOrEmailAddress, String password, String tenancyName) in C:\Projects\NEO\Main\SAH.NEO\src\SAH.NEO.Web.Core\Controllers\TokenAuthController.cs:line 197 at SAH.NEO.Controllers.TokenAuthController.d__8.MoveNext() in C:\Projects\NEO\Main\SAH.NEO\src\SAH.NEO.Web.Core\Controllers\TokenAuthController.cs:line 57 β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at lambda_method(Closure , Object ) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__12.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__10.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__23.MoveNext() INFO 2018-05-15 11:19:55,042 [9 ] etCore.Mvc.Internal.ObjectResultExecutor - Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext. INFO 2018-05-15 11:19:55,042 [9 ] ore.Mvc.Internal.ControllerActionInvoker - Executed action SAH.NEO.Controllers.TokenAuthController.Authenticate (SAH.NEO.Web.Core) in 52.0181ms ERROR 2018-05-15 11:19:55,042 [9 ] Microsoft.AspNetCore.Server.Kestrel - Connection id β€œ0HLDQ0BD8TOQA”, Request id β€œ0HLDQ0BD8TOQA:00000003”: An unhandled exception was thrown by the application. System.InvalidOperationException: StatusCode cannot be set because the response has already started. at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame.set_StatusCode(Int32 value) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value) at Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 value) at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.<>c.b__16_0(HttpContext context) at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.StaticFiles.DefaultFilesMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.d__6.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Owin.WebSocketAcceptAdapter.<>c__DisplayClass6_0.<b__0>d.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.d__4.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at SAH.NEO.Web.Host.Startup.Startup.<>c.<b__4_1>d.MoveNext() in C:\Projects\NEO\Main\SAH.NEO\src\SAH.NEO.Web.Host\Startup\Startup.cs:line 124 β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.d__7.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.d__2.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.d__11.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext() β€” End of stack trace from previous location where exception was thrown β€” at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)

I have changed the GetLoginResultAsync to sync method as I thought it might be this that sometime works sometime does not but it was not it.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:37 (12 by maintainers)

github_iconTop GitHub Comments

6reactions
ryancyqcommented, Oct 28, 2018

I have taken a deeper look at the issue. This seems to be a problem when using UnitOfWork.IsTransactional with PostgreSQL

When a new user is created via AbpLoginManager.TryLoginFromExternalAuthenticationSources(). https://github.com/aspnetboilerplate/aspnetboilerplate/blob/cf87dd654bab699dbb5962003efd55ac945e3e2c/src/Abp.ZeroCore/Authorization/AbpLoginManager.cs#L307-L323

The user entity is being tracked in Microsoft.EntityFrameworkCore.ChangeTracker.Entries() after SaveChangesAsync() is called followed by await UserManager.CreateAsync(user); .

However, the user is then updated in CreateLoginResultAsync() after the entity creation while it is still under the same transaction. https://github.com/aspnetboilerplate/aspnetboilerplate/blob/cf87dd654bab699dbb5962003efd55ac945e3e2c/src/Abp.ZeroCore/Authorization/AbpLoginManager.cs#L170-L201

https://github.com/aspnetboilerplate/aspnetboilerplate/blob/cf87dd654bab699dbb5962003efd55ac945e3e2c/src/Abp.ZeroCore/Authorization/AbpLoginManager.cs#L205-L234

The exception is thrown when UserManager.UpdateAsync(user) checks for old username from database. https://github.com/aspnetboilerplate/aspnetboilerplate/blob/cf87dd654bab699dbb5962003efd55ac945e3e2c/src/Abp.ZeroCore/Authorization/Users/AbpUserManager.cs#L613

And a new scope is used to retrieve old username https://github.com/aspnetboilerplate/aspnetboilerplate/blob/cf87dd654bab699dbb5962003efd55ac945e3e2c/src/Abp.ZeroCore/Authorization/Users/AbpUserStore.cs#L1221-L1232

By default, EfCoreUnitOfWork uses IsolationLevel.ReadUncommitted but it is treated as IsolationLevel.ReadCommitted in PostgreSQL

PostgreSQL’s Read Uncommitted mode behaves like Read Committed.

https://github.com/aspnetboilerplate/aspnetboilerplate/blob/cf87dd654bab699dbb5962003efd55ac945e3e2c/src/Abp.EntityFrameworkCore/EntityFrameworkCore/Uow/DbContextEfCoreTransactionStrategy.cs#L38

However, this is the behaviour that currently not supported by PostgreSQL as stated below.

Read Committed is the default isolation level in PostgreSQL. When a transaction uses this isolation level, a SELECT query (without a FOR UPDATE/SHARE clause) sees only data committed before the query began; it never sees either uncommitted data or changes committed during query execution by concurrent transactions.

https://www.postgresql.org/docs/current/static/transaction-iso.html#XACT-READ-COMMITTED

I would suggest to disable IsTransactional for UnitOfWork if you are using PostgreSQL.

public override void PreInitialize() {
    // more code ..
    Configuration.UnitOfWork.IsTransactional = false;
    // more code ..
}
1reaction
seblucascommented, Jan 16, 2019

Replying to myself, I just need to do that in TokenAuthController.cs :

        [UnitOfWork(isTransactional: false)]
        public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model)
Read more comments on GitHub >

github_iconTop Results From Across the Web

External authentication not working when configured in ' ...
The 'Authentication / Authorization' settings are seemingly just a pleasant front-end to set environment variables. This is not very wellΒ ...
Read more >
Troubleshooting Azure Active Directory B2B collaboration
External user doesn't exist already in a federated domain. If you're using federation authentication and the user doesn't already exist in AzureΒ ...
Read more >
Error External authentication with Azure AD
Solved: Hi all, I am getting the following error when trying to set up Azure AD with my portal. I have set up...
Read more >
External authentication using active directory is not working
FileMaker Server can be joined to an Active Directory Domain and based on that, users can be authenticated for access to hosted files...
Read more >
Troubleshoot User Authentication
If SSO does not work for a user, it is important to verify whether manual authentication (a prompt for typed user credentials) works...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found