grails-spring-security-core icon indicating copy to clipboard operation
grails-spring-security-core copied to clipboard

isFullyAuthenticated() leads to redirect-loop

Open robertoschwald opened this issue 5 years ago • 16 comments

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

  1. Secure a resource in staticRules or interceptUrlMap with IS_AUTHENTICATED_FULLY or isFullyAuthenticated() el expression.
  2. Login using remember-me
  3. Close browser, and re-access the application to login using remember-me
  4. 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

robertoschwald avatar Dec 02 '18 10:12 robertoschwald

Anyone has a workaround (other than disabling remember-me)?

bassmartin avatar Dec 19 '18 14:12 bassmartin

Same happens with Grails 3.3.9

ginchauspe avatar Jan 03 '19 20:01 ginchauspe

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

ddelponte avatar Apr 02 '19 18:04 ddelponte

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)

bassmartin avatar Apr 02 '19 18:04 bassmartin

Same here. Doesn't work with Safari.

robertoschwald avatar Apr 04 '19 07:04 robertoschwald

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

ddelponte avatar Apr 04 '19 19:04 ddelponte

I cherry picked the filter order change to master branch as well.

https://github.com/grails-plugins/grails-spring-security-core/commit/d8757fa1b2298d376813ff8598d0cd84c63037d0

sdelamo avatar May 30 '19 08:05 sdelamo

Closing. The related PR has been merged to the 3.3.x branch and merged to master

ddelponte avatar Jun 03 '19 18:06 ddelponte

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.

bobbywarner avatar Oct 23 '19 02:10 bobbywarner

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.

rwinch avatar Nov 18 '19 17:11 rwinch

@ddelponte please remove fixed label, as the problem is still unfixed.

robertoschwald avatar Dec 16 '19 12:12 robertoschwald

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.

aentwist avatar Aug 17 '20 17:08 aentwist

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...

azavisha-snap avatar Apr 30 '21 22:04 azavisha-snap

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.

aentwist avatar May 02 '21 02:05 aentwist

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)

sagrawal31 avatar May 02 '21 12:05 sagrawal31

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.

azavisha-snap avatar May 03 '21 17:05 azavisha-snap