Summary
It would appear that when supplying a custom AuthenticationFailureHandler to formLogin().failureHandler(), the resulting methods cause the failureUrl on the handler to be ignored, i.e. permitAll won't recognise the failureUrl.
As a result, when login authentication fails, and the RedirectStrategy redirects to the failureUrl, what we get is a further redirect back to /login (loginUrl)
Actual Behavior
AbstractAuthenticationFilterConfigurer.failureUrl(String failureUrl)
states that this method is a shortcut for calling AbstractAuthenticationFilterConfigurer.failureHandler(AuthenticationFailureHandler authenticationFailureHandler)
However, the first sets this.failureUrl
Whereas, the 2nd method sets it to null
and sets this.failureHandler to the passed in AuthenticationFailureHandler.
What this means is that when .permitAll() is set, the failureUrl is null at the time of init.
/login?error (failureUrl) results in a 302 to login
Expected Behaviour
When configuring the form, not calling .failureHandler simply results in an instance of AuthenticationFailureHandler being created and the failureUrl set to /login?error.
Alternatively, calling failureUrl("/login?error)" does the same.
However, calling .failureHandler(AuthenticationFailureHandler failureHandler) does not have the same behaviour, due to failureUrl not being set and the corresponding failureHandler.failureUrl never being accessed (note: it doesn't have a getter anyway)...
Configuration
Version
4.1.3
Haven't checked other versions, but have checked the 4.1.x branch and the code matches up.
So the question is:
How would I supply my own authenticationFailureHandler to formLogin and have its failureUrl permitted?
I believe it would work by passing my own failureUrl to http.authorizeRequests().antMatchers(<here>).permitAll()?
It just seems counter-intuitive for .failureHandler not to use the passed in handler's failureUrl, especially when the javadoc explicitly says .failureUrl(String failureUrl) is a shortcut for calling .failureHandler.
I've been attempting to figure this out for the past day, so I'm thinking there's probably just a different path I should be taking that I am not aware of...
Comment From: eleftherias
Thanks for reaching out @rmckirby.
You are correct that the Javadoc incorrectly states that failureUrl(String) is a shortcut for invoking failureHandler(AuthenticationFailureHandler).
We have created gh-9229 to fix that.
You are also correct that you would explicitly need to provide access to the URL that you are using in the failureHandler by setting .authorizeRequests().antMatchers(<here>).permitAll().
See this comment for more details.