grails-spring-security-core
grails-spring-security-core copied to clipboard
isFullyAuthenticated() leads to redirect-loop
In Grails 3.3.x, isFullyAuthenticated() / IS_FULLY_AUTHENTICATED rule does not work as expected.
When accessing a resource secured by isFullyAuthenticated() using remember-me, a redirect to LoginController.full() is expected, but a redirect loop between login and protected resource happens until the browser gives up.
Steps to Reproduce
- Secure a resource in staticRules or interceptUrlMap with IS_AUTHENTICATED_FULLY or isFullyAuthenticated() el expression.
- Login using remember-me
- Close browser, and re-access the application to login using remember-me
- Access the IS_AUTHENTICATED_FULLY secured resource
Expected Behaviour
Re-login page is shown
Actual Behaviour
Redirect loop between login and protected resource happens until the browser gives up. It seems no AuthenticationException is thrown on a remember-me access to a isFullyAuthenticated() resource, therefore LoginController.auth() is called, and not LoginController.full()
Environment Information
- Operating System: OSX 10.14
- GORM Version: 6
- Grails Version (if using Grails): Tested with 3.3.5 and 3.3.8
- JDK Version: 1.8_181 Zulu
- Plugin version: 3.2.3
Example Application
Example simple project showing the problem see https://github.com/robertoschwald/spring-security-core-fully-auth-error
Anyone has a workaround (other than disabling remember-me)?
Same happens with Grails 3.3.9
May I ask which browser(s) you are testing with?
A video demonstrating it working as expected in Chrome may be viewed at https://drive.google.com/open?id=1WiYQjoKqL-ycvMNJ6Bbwm6c5kRpHuqc2
I tested this with:
- macOs
- Chrome Version 73.0.3683.86
- Java 1.8.0_172 as well as Java 1.8.0_202-zulu
I can reproduce the issue with Safari Version 12.0.3 (14606.4.5) I works as expected with Chrome Version 73.0.3683.86 (Official Build) (64-bit)
Same here. Doesn't work with Safari.
Thank-you everyone for your patience and your feedback... and the sample app demonstrating the problem!
I've created a PR that will fix this issue. The PR is #571
I cherry picked the filter order change to master
branch as well.
https://github.com/grails-plugins/grails-spring-security-core/commit/d8757fa1b2298d376813ff8598d0cd84c63037d0
Closing. The related PR has been merged to the 3.3.x branch and merged to master
Changing the filter order is not the correct fix for this issue as "remember me" does not work at all currently. So, I'm reverting the commit and will continue to look for a solution to this issue that does not involve reordering the filters.
This appears to be what is happening:
- The user makes a request as a remember me user to /secure/index
- Spring Security notices they are not fully authenticated and redirects to /login/auth
- The RememberMeAuthenticationFilter sees that the remember me token is present and logs the user in
- The RememberMeAuthenticationFilter has a success handler set (not typical) and then redirects the user to /secure/index again
- The process is repeated
In a standard Spring Security setup RememberMeAuthenticationFilter just continues processing the FilterChain by making sure the successHandler is null. If you really want a successHandler to be set, it is your responsibility to avoid a redirect loop.
Another point is that Grails LoginController will perform a redirect to success handler if the user is logged in which means the login page will not be displayed unless the user overrides the login page.
@ddelponte please remove fixed label, as the problem is still unfixed.
I am also encountering this issue, using the latest version of the plugin 4.0.2
. The Grails version is irrelevant and should be removed from the title. I am running Grails 4.0.4
.
It seems like a very important problem. How can we use remember me while this issue is still unresolved? Why is this not a priority? At least some workaround would have been nice after 2+ years...
Due to the fact that Grails has no traction and the momentum here has fallen off so far this year, I wouldn't expect too much. Feel free to open a pull request.
Agree with you @aentwist about slow development/response sometimes by the Grails community but the link you shared (https://www.quora.com/Is-Grails-framework-dead) is quite old and there has been a big movement in terms of development in Grails framework which has made it far better and amazing.
Requesting Grails community and maintainers of this plugin to pick this issue on high priority.
(PS. I'm one of the commentators in that Quora question)
Here is my workaround until the problem is resolved.
The main symptom of this problem appears to be that when a resource secured with isFullyAuthenticated()
is accessed while the user is authenticated with remember-me, they get sent to LoginController.auth()
instead of LoginController.denied()
. Normally, denied()
redirects those users to full()
. So the idea is to put the same conditional redirect at the beginning of auth()
: if authenticated with remember-me, then redirect to full()
.
This has a side effect: if a remember-me authenticated user opens (or gets redirected to) the login page, they will actually see the login page, instead of being automatically redirected to successHandler.defaultTargetUrl
.