- ABP Framework version: v8.1.3
- UI Type: Angular
- Database System: EF Core (Oracle)
- Auth Server Separated OpenID Server
I still can't get logout to work consistently in my Angular applications.
First of all, I commented the line - just for your information:
{
path: '',
pathMatch: 'full',
loadChildren: () => import('@my-home-page-package').then(m => m.MyHomeModule),
// canActivate: [AuthGuard] // This was a logout blocker
}
Now: A) If i use this code:
@Injectable()
export class MyServerErrorInterceptor implements HttpInterceptor {
constructor(private router: Router) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
this.router.navigate(['/']);
return EMPTY;
} else {
return throwError(error);
}
})
);
}
}
and click "Logout" link in the user menu, the logout seems to be working as expected from tab 1 in the browser. However if I have another page being open from the same site in tab 2 - it is not redirected to Login page: instead, I come up with an empty (no navigation menu) home page shown in this tab;
B) If i replace ['/']
with ['/login']
in the code above - both tabs react on this, however I end up with the endless loop, when both tabs try to do something and it never ends;
Also - if i have only one tab of the application opened in the browser, I still have a weird situation, when after getting connect/revocat
request (twice, btw - ??) and several 401 API requests, I see (so i see traditional openid-configuration
and so forth), so I am not actually logged out - but redirected to a home page;
C) If i emulate the situation with a token expiration - removing "local storage" data in the browser, I expect to be redirected to Login page on the next request attempt (instead of giving me error 401). So the setting (B) provides this, however setting (A) redirects me to a no-menu home page;
And in general, logout process visually does not look good: I expect if a user clicks "Logout" - he is redirected to Login page straight away. Instead, I see the navigation menu is being disappeared and still observing a home page while some server operations are taking place;
I have some Middleware in my OpenID Server module to do cleaning work on httpContext.Request.Path.Value == "/connect/logout"
scenario (B) (but works fine with scenario (A) - the exception does not happen). So I commented it, but it RANDOMLY affected the described scenario (sometimes it did, sometimes it did not):
public async Task InvokeAsync(HttpContext httpContext, IAbxRequestContext requestContext, IdentityUserManager userManager)
{
await _next(httpContext);
if (httpContext.Request.Path.Value == "/connect/logout")
{
await OnSessionEndRequestAsync(httpContext, userManager);
}
}
private async Task OnSessionEndRequestAsync(HttpContext httpContext, IdentityUserManager userManager)
{
try
{
var user = await userManager.GetUserAsync(httpContext.User); //IF IT GETS INVOKED AND CRASHES - IT SEEMS TO AFFECT THE LOGOUT
//Some cleaning routine - accessing DB, removing entries
}
catch(Exception ex)
{
_logger.LogError(ex, "Session End handling error");
}
}
Thus, I have no clue what might be a real root cause of the logout issue.
I kindly ask you to provide me with the correct settings (code) for a front-end and a back-end settings which might be relevant to the situation.
I cannot provide you with our code, sorry.
My suggestion is to start with a root cause of the exception in the call above. It is:
at System.Threading.CancellationToken.ThrowOperationCanceledException() at System.Threading.CancellationToken.ThrowIfCancellationRequested() at Volo.Abp.Identity.IdentityUserStore.FindByIdAsync(String userId, CancellationToken cancellationToken) at Castle.Proxies.IdentityUserManagerProxy.FindByIdAsync_callback(String userId) at Castle.Proxies.Invocations.UserManager
1_FindByIdAsync.InvokeMethodOnTarget() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.DynamicProxy.AbstractInvocation.ProceedInfo.Invoke() at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue
1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func
3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
whereas httpContext.User
is OK (data is ok and it is authenticated).