Angular-auth-oidc-client: AutoLoginGuard appears to cause some sort of infinite loop.

Created on 19 Apr 2021  Â·  17Comments  Â·  Source: damienbod/angular-auth-oidc-client

Describe the bug
Attempting to access the root route (/) with AutoLoginGuard present intermittently causes an infinite login loop that crashes the browser.

To Reproduce
Steps to reproduce the behavior:

  1. Secure all routes with AutoLoginGuard
  2. Sign out of the identity server
  3. Open console
  4. Navigate to web app
  5. You may be redirected to the identity server the first time, but navigate back to the webapp.
  6. You should start to see a login loop.

Expected behavior
Expected library to login user and to return them back to the app homepage.

Screenshots
image

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Chrome, Chromium Edge
  • Version: 90

Additional context
You can force this behavior using the sample-code-flow-auto-login sample. Just add AutoLoginGuard to the home route, and you should get the loop after you sign in to the app.

Our end-goal is to have the webapp automatically sign the user in as soon as they access the app. We don't want any sort of landing page. Prior to the existence of the AutoLoginGuard, we managed to force this behavior using an approach similar to the sample-implicit-flow-google demo (though we needed to change the localstorage key name as redirect was being used by the library and causing issues.

question

All 17 comments

Hey @JerrettDavis, thanks for the issue.

Have you checked that you _do not_ have the checkAuth call when using the auto-login guard at the home route? The sample has the call because there exist two ways of auto-login. Either you call the checkAuth() manually or your home route does that with the AutoLoginGuard. If you want to project your case to the sample you have to remove the manual checkAuth() call.

docs

Thanks for the prompt reply @FabianGosebrink! I am actually using checkAuth in various services, should those be replaced with isAuthenticated$ to prevent the login attempts?

This should work, otherwise, it is a bug. The checkAuth() method is gonna be called from the AuthGuard and then all values should be set. Let us know if it works.

Could you solve the issue?

I've been unable to test the solution in our own codebase due to other backlog items, but it did correct the issue with the demo project, so I have high hopes.

I'd say go ahead and close this issue, I can open another or bump this if the issue resurfaces.

Thanks for the help.

Perfect, just let us know if the problem still occurs and if yes we will get that going and help you to solve it :), thanks!

@FabianGosebrink
I think this issues occured for me. No checkAuth() calls prior to AuthLoginGuard. My investigation showed me that loop is occuring because after checking authentication it reads previously stored redirect path (saved before the first redirect to identity provider) and goes there. In my case the path is guarded by AuthLoginGuard, so the cycle repeats, and repeats, and repeats

Do you have a sample repo to reproduce the issue? You can take a config from our samples.

I'll try to provide one

I'm seeing the same looping issue when using AutoLoginGuard on the default route and not calling checkAuth.

I changed the sample "sample-code-flow-auto-login" to use AutoLoginGuard on the default route and removed the call to checkAuth. For some reason it still works fine (no looping).

The only differences I see between my app and the sample at this point are I'm using Azure AD as the IdP and using config over http.

I noticed the app created a local storage variable named redirect as shown below. The value doesn't look like something the redirect should be set to but I could be wrong.

This is my config and routing:

const setupAction$ = httpClient.get('/api/azuread-client-settings').pipe(
map((authConfig) => {
return {
stsServer: authConfig.stsServer,
clientId: authConfig.clientID,
redirectUrl: window.location.origin,
postLogoutRedirectUri: window.location.origin,
scope: 'openid profile email api://98d5e485-770f-47c2-a836-35c8cd90e103/access_as_user',
responseType: 'code',
silentRenew: true,
triggerAuthorizationResultEvent: true,
startCheckSession: false,
maxIdTokenIatOffsetAllowedInSeconds: 600,
logLevel: LogLevel.Debug,
historyCleanupOff: true,
silentRenewUrl: window.location.origin + '/silent-renew.html'
};
}),

const appRoutes: Routes = [
{
path: '', redirectTo: 'home', pathMatch: 'full'
},
{
path: 'home', component: HomeComponent, canActivate: [AutoLoginGuard]
}

No calls to checkAuth within the application

Recurring within the looping is also this 401:
​ GET https://graph.microsoft.com/oidc/userinfo 401 (Unauthorized)

LocalStorageRedirect

sample-code-flow-auto-login.zip
@FabianGosebrink
So I toyed a bit with auto login sample. What I discovered that if you guard homeroute (as is required in my app -- no path is public) then it stops working correctly (i.e. start looping) if you remove checkAuth() call from app.component. I don't know if that's a bug or expected behaviour and I just set it up incorrectly
I attached a zip with sample. If that's more convenient to you I can create a repo

I should also add that if you leave checkAuth() call it doesn't help either. When you login then logout then login again, it gets stuck in a loop

A package.json would be fine :) Could you add it to the repo? A repo would be great then we can compare the fix if we create one.

Have done a PR where the autologin works at my place https://github.com/grffn/demo-auto-login/pull/1

Just a small additional data point relating to the AutLoginGuard. While I have solved the infinite redirect loop (I think), the guard occasionally produces a bad redirect. I can't seem to reproduce it with any regularity, but it happens occasionally during live reloads.

I get something along the lines of this:
image

Here are the applicable routes:
```typescript
const appRoutes: Routes = [
{path: '', pathMatch: 'full', redirectTo: 'home'},
{
path: 'home',
canActivate: [AutoLoginGuard],
loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule)
}
{path: '**', component: PageNotFoundComponent}, // Wildcard route for a 404 page
];
````

All the AutoLoginGuards are present only in the app-routing.module, the guard isn't necessary in the child routes since it's secured at the root.

@FabianGosebrink please chime in if this should be a separate issue.

I can attempt to build a reproducible example, if needed, but maybe the answer is obvious based on just the above information.

I also noticed a infinity loop in some special cases. The reproducing steps are:

  1. Call a route, which is secured by the AutoLoginGuard
  2. Now you should be redirected to the Login, do not login.
  3. Now call the secured route again
  4. Now the loop is started

I will try to offer you a min repro with this behavior.

What I noticed is that we also have very much calls to the authorize-url and values in the storage will be updated continuesly.

Was this page helpful?
0 / 5 - 0 ratings