Providing an AuthenticationSuccessHandler
for a RememberMeAuthenticationFilter
breaks the filter chain, therefore I would like to override its onSuccessfulAuthentication
method by providing a custom implementation of RememberMeAuthenticationFilter
. But that seems to be quite complicated or elaborate when using simple Java Config.
Providing an ApplicationEventPublisher
is not a solution if one needs access to HttpServletRequest
or HttpServletResponse
.
I managed to do it, but it looks like a hack - is there a better way?
I've done it this way:
http.rememberMe().addObjectPostProcessor(new ObjectPostProcessor<RememberMeAuthenticationFilter>() {
@Override
public <O extends RememberMeAuthenticationFilter> O postProcess(O object) {
RememberMeAuthenticationFilter newFilter = new RememberMeAuthenticationFilter(
(AuthenticationManager) getByReflection(object, "authenticationManager"),
(RememberMeServices) getByReflection(object, "rememberMeServices")
) {
@Override
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) {
// business logic
}
};
return (O) newFilter;
}
private <O extends RememberMeAuthenticationFilter> Object getByReflection(O object, String name) {
Field field = ReflectionUtils.findField(object.getClass(), name);
ReflectionUtils.makeAccessible(field);
return ReflectionUtils.getField(field, object);
}
});
If you want to implement a custom behavior when authentication process (with remember me feature) is success you can try:
Define a new filter such as:
public class CustomRememberMeAuthenticationFilter extends RememberMeAuthenticationFilter {
@Override
protected void onSuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final Authentication authResult) {
super.onSuccessfulAuthentication(request, response, authResult);
if (authResult != null) {
// process post authentication logic here..
}
}
}
Set the customer filer in security chain:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/","/login*").permitAll()
//...
http
.addFilter(rememberMeAuthenticationFilter())
//...
}
@Bean
protected RememberMeAuthenticationFilter rememberMeAuthenticationFilter(){
return new CustomRememberMeAuthenticationFilter(authenticationManager(),rememberMeServices());
}
Check this in order to create your (authenticationManager(),rememberMeServices()
In the previous snippet, custom filter is just added. If does not works, you must research and find the exact Filter in the chain to insert your custom filter: addFilterBefore, addFilterAfter, addFilterAt.
Check this add filter methods
Finally remove the default http.rememberMe() in order to use your own filter. Because the remember-me namespace element already inserts a RememberMeAuthenticationFilter so it will still take precedence over yours, since it comes before it in the filter chain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With