New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question]: Why is AutoLoginAllRoutesGuard not recommended? #1549
Comments
Hey, thanks for asking. Like written in the docs, and you cited it very correct, an SPA normally needs a point to set up the auth when it gets redirected from the IDP to the app itself. If you think of the state of the app, which is not authorized in this case, but the state of the "system" (Your IDP, maybe backend and SPA) is "currently authorizing". Because you entered the correct credentials and therefore as the user, you should even be "authorized" at this point. So things are a little more complex here. You land in the app with a code and the SPA needs to do a few calls (exchange the code with a token, etc.) but for the app at this point you are NOT authenticated. This is why you technically need a route which is publically accessible without being authenticated to have an entry point to get all the things going. The lib does that for you, if you call the "checkAuth()" method. So in your callback-component (for example) you can call "checkAuth()" and wait for the response coming back. The lib provides a login response then and in positive case you can redirect to your real application, your dashboard, starting page or whatever. So there is like a "handshake" going on between your IDP and your app. It is not just SPA --> IDP --> SPA, like the user sees it. What we tried to do is covering that case with a guard, because guards are called before the route is being called, and the component is shown. Because the mentioned callback component was not being used for many users of this lib and the question "How can I secure my complete app?" was asked many times. But the guard is only one standard way of "checking and redirecting". We have encountered that we had many "bugs" or better "questions" in exactly that procedure: Auth with many different IDPs, redirecting back and forth to the correct route in every case for every app using this lib. We tried to solve it with this guard. It all could have been solved with this one public route which provides you better control over the step between the "User provided correct credentials and therefore for the USER you are logged in" and the step "The SPA HAS a valid ID- and refresh token, all the timers for refresh are set up, and we are good to go". This is a problem we developers have to solve. The guard was one attempt, but if this is not working in your case, with the docs we wanted to mention the solution with the public route, which is easier in terms of seeing what is going on, because it represents the steps in between better, but of course not that comfortable as just putting a guard on your route, and you're good to go. On a personal note, I regret implementing this guard because for me, it seems it created more bugs, questions and confusion to the users than it helped them. Just having that one public route would have been the easier way. But you are always smarter in the end :-) I hope I could help you a bit. |
Thanks for the detailed explanation. But just to be clear: the recommended approach for "I want to secure my complete app" would be:
Unfortunately, I am still struggling to implement something like that. So far I have something that mostly works (see code below). I can login and navigate to all routes. If am not logged in and try to access any of the protected routes the login flow is automatically initiated. But there are at least 2 cases where it is not working correctly:
For the first case it seems that And for the second case it seems that the
But that also seems redundant because the logic for that is already implemented in It would be great if someone could point out what I am missing.
|
You have to call |
@FabianGosebrink ok, thanks. Calling |
Is there a working sample for this pattern available? This seems to conflict other information mentioned elsewhere, where you shouldn't call checkAuth() more than once. I don't see how you are supposed to have checkAuth() in the AppComponent.onInit as well as within the callback component without it being called twice. |
I've got the same question as @KegLand. I've implemented the callback component and call checkAuth() in the AppComponent.onInit. I can see the method is being called twice. I'm not sure how you would implement it otherwise though. Any help would be welcomed. |
I have to correct myself. Calling This was no problem in my first tests using Azure AD as IDP. It seems that Azure AD ignores the second request. But when I tested against a Keycloak 20.0.3 Keycloak would return a 400 Bad Request for the second call to the token endpoint. And that caused issues in my app, like redirect to the originally requested page after login was not working properly. Sometimes the user would be redirected to the "home" page instead. Logout and logging in as a different user in the same tab would not work properly, etc. So it seems that the current version of auto-login for all routes sample, which only calls However, it still has one flaw, namely the that reloading the page (F5) - or accessing another page by manually changing the URL in the browser's address bar - when already logged in will break the sample's It seems that the A workaround could be to change
This will ensure that
@FabianGosebrink why do Should |
In fact, it is not only |
@FabianGosebrink I have the same issue as the guys have. I don't have public pages except /callback, and in my case, i have the method checkAuth called twice and on the second call I get 400 error (spring oauth2). How we can deal with it? |
Having the same issue as @alexeek when following the advice given here. By having a checkAuth() call in both the app component Init and the public callback component, it results in two requests to the token endpoint. In my case this causes a 400 error result from my IDP (Identity server) and my logic to handle completion of authentication process in the callback component is failing as it is the second request and gets the error result. Is there any more guidance on how to avoid this duplicate request issue? I've tried not having the checkAuth() call in the app component, but then I've not been able to correctly handle page refreshes when there is an active session. |
Try the checkAuth() in the app.component only. |
Hey @FabianGosebrink , facing the same issue with checkAuth() method which i used in callback component and also app component with AutoLoginPartialRoutesGuard |
:) |
Calling The sample only calls |
You can call this method wherever you want, but it has to be called when you are getting redirected from the sts. |
I had the same problem as @heapifyman where So it seems that for my situation (and seemingly others) it is required to call |
True. My comment is not complete. |
Hi, I'm currently trying to implement this exact "protect all app" thing using the discussed patterns here. The solution that seems to work best in my case is to put this checkAuth call in the APP_INITIALIZER code portion. But at this point the actual auth callback public route seems basically useless... My init code looks like this:
So basically, I think this fixes the issue by forcing the app to wait for the auth handshake stuff to complete before any component is initialized. Regards, |
No, this is another method and should be fine imho :) |
Thx for the quick answer! |
You are very welcome and thanks for using our lib :) |
Its also worth mentionning that the AutoLoginPartialRoutesGuard guard may pass BEFORE checkAuth() is actually called, probably when a valid token is found in storage. In my case, i wanted to fetch a resource from a remote server once the user is authenticated but before my protected routes could be displayed. I was relying on another guard waiting on a value to be emitted by an observable, but that value was only fetched once my checkAuth call had completed. It appeared the angular app was hanging. A solution was to call |
What Version of the library are you using?
14.1.5
Question
The documentation for
AutoLoginAllRoutesGuard
states:I may have missed it somewhere in the documentation but I could not find any explanation why it is not recommended.
Is the implementation considered unstable or is there maybe some fundamental technical issue?
Could someone provide some details why exactly it is not recommended?
And would it make sense to add that explanation to the above documentation?
The docs continue:
Is there an example application available that demonstrates how to do that? And would it make sense to add it to the samples for this project because it is the recommended way of implementing this use case - maybe it would even replace the current sample for
AutoLoginAllRoutesGuard
?The text was updated successfully, but these errors were encountered: