Spring Security Concurrent Session Control - spring

I am trying to restrict user session to one at a time from anywhere. But it doesn't work. When I try to access the application with the same user on two navigator, I have access.
I noticed that when a user connects to the application on two different machines to start printing two different reports, there is an print that comes out instead of the other.
Thanks for help.
My Security config class :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
/*#Autowired
private DataSource dataSource;*/
private AccessDeniedHandler accessDeniedHandler;
private AuthenticationSuccessHandler authenticationSuccessHandler;
private AuthenticationFailureHandler authenticationFailureHandler;
private UserDetailsService userDetailsService;
#Autowired
public SecurityConfiguration(
#Qualifier("customAccessDeneiedHandler")AccessDeniedHandler accessDeniedHandler,
#Qualifier("customSuccessHandler")AuthenticationSuccessHandler authenticationSuccessHandler,
#Qualifier("customAuthenticationFailureHandler")AuthenticationFailureHandler authenticationFailureHandler,
#Qualifier("customUserDetailsService")UserDetailsService userDetailsService) {
this.accessDeniedHandler = accessDeniedHandler;
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.authenticationFailureHandler = authenticationFailureHandler;
this.userDetailsService = userDetailsService;
}
/* (non-Javadoc)
* #see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
*/
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO Auto-generated method stub
//super.configure(auth);
auth.userDetailsService(userDetailsService) //auth.userDetailsService(utilisateurDetailsService)
.passwordEncoder(passwordEncoder());
}
//Authorization
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
//.antMatchers("/").permitAll()
.antMatchers("/ajouterassure", "/ajouterattributaire", "/ajouterbeneficiaire", "/ajouterpiecejustificative",
"/creerbordereauemission", "/creerbehorscoordination", "/creerbordereaupaie", "/ajouteravance",
"/creerbeavanceannuelle")
.hasAnyRole("DGA", "DGAA", "DR", "DRA", "CC", "CCA", "CI", "AS", "GUICHET", "CE", "CAP", "ADMIN") //.hasRole("ADMIN")
.antMatchers("/ajoutercentre", "/ajouteretablissementpaie", "/ajoutertypepj", "/ajoutertypedette",
"/ajoutersexe", "/ajoutersituationbeneficiaire", "/ajoutercategoriebeneficiaire",
"/ajoutercategorieattributaire", "/ajouterrevalorisation").hasAnyRole("DGA", "ADMIN") //hasAnyRole("CAP", "ADMIN")
.antMatchers("/payerdecompte").hasAnyRole("CAISSIER", "ADMIN")
.antMatchers("/ajouterutilisateur").hasAnyRole("CI", "ADMIN")
.anyRequest().authenticated()
.and()
//.httpBasic()
.formLogin()
.loginPage("/login")
//.loginProcessingUrl("/login")
.usernameParameter("identifiant")
.passwordParameter("mot_de_passe")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
//.defaultSuccessUrl("/")
.permitAll()
.and()
.logout().permitAll()
.and()
.sessionManagement() //Session controle concurence access
.maximumSessions(1)
.expiredUrl("/login?expired")
.sessionRegistry(sessionRegistry);
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
//Session controle concurence access
//http.sessionManagement().maximumSessions(1);
}
/* (non-Javadoc)
* #see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.WebSecurity)
*/
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/resources/templates/errors/**", "/static/**", "/css/**", "/images/**", "/var/signatures/**");
//web.ignoring().antMatchers("/static/**");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
#Bean(name = "sessionRegistry")
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
#Autowired
#Lazy
private SessionRegistry sessionRegistry;
}

[Just in case someone finds it useful.]
Always add hashcode and equals methods in custom UserDetails class along with the below config in the spring security configuration class for the concurrent sessions to work.
protected void configure(HttpSecurity http) throws Exception
{
http.sessionManagement().maximumSessions(1);
}
#Bean
public HttpSessionEventPublisher httpSessionEventPublisher()
{
return new HttpSessionEventPublisher();
}

You need to just add .maxSessionsPreventsLogin(true) after maximumSessions(1) and it stop logging in from other places util session expires here. So your configure method should look like this :-
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
//.antMatchers("/").permitAll()
.antMatchers("/ajouterassure", "/ajouterattributaire", "/ajouterbeneficiaire", "/ajouterpiecejustificative",
"/creerbordereauemission", "/creerbehorscoordination", "/creerbordereaupaie", "/ajouteravance",
"/creerbeavanceannuelle")
.hasAnyRole("DGA", "DGAA", "DR", "DRA", "CC", "CCA", "CI", "AS", "GUICHET", "CE", "CAP", "ADMIN") //.hasRole("ADMIN")
.antMatchers("/ajoutercentre", "/ajouteretablissementpaie", "/ajoutertypepj", "/ajoutertypedette",
"/ajoutersexe", "/ajoutersituationbeneficiaire", "/ajoutercategoriebeneficiaire",
"/ajoutercategorieattributaire", "/ajouterrevalorisation").hasAnyRole("DGA", "ADMIN") //hasAnyRole("CAP", "ADMIN")
.antMatchers("/payerdecompte").hasAnyRole("CAISSIER", "ADMIN")
.antMatchers("/ajouterutilisateur").hasAnyRole("CI", "ADMIN")
.anyRequest().authenticated()
.and()
//.httpBasic()
.formLogin()
.loginPage("/login")
//.loginProcessingUrl("/login")
.usernameParameter("identifiant")
.passwordParameter("mot_de_passe")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
//.defaultSuccessUrl("/")
.permitAll()
.and()
.logout().permitAll()
.and()
.sessionManagement() //Session controle concurence access
.maximumSessions(1)
.expiredUrl("/login?expired")
.sessionRegistry(sessionRegistry);
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
//Session controle concurence access
//http.sessionManagement().maximumSessions(1);
}

Related

Configure antMatchers in Spring Security

I have this Spring Security configuration in Wildfly server:
#Configuration
#EnableWebSecurity
#Import(value= {Application.class, ContextDatasource.class})
#ComponentScan(basePackages= {"org.rest.api.server.*"})
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthEntryPoint authenticationEntryPoint;
#Autowired
MyUserDetailsService myUserDetailsService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService);
auth.authenticationProvider(authenticationProvider());
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(myUserDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/v1/notification")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
#Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
I want to configure Spring security to permit all requests send to
http://localhost:8080/war_package/v1/notification but unfortunately I get always Unauthorized. Do you know what is the proper way to configure this?
You need to enable ResourceServer and add configure(HttpSecurity http) there.
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/v1/notification")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
}

SessionRegistry returns an empty list of authenticated users

I have an event listener, which when it receive the event that the user has changed their password invalidates the session. This is the code:
#Component
public class UserListener {
private static Logger logger = LoggerFactory.getLogger(UserListener.class);
#Autowired
private SessionRegistry sessionRegistry;
#EventListener
public void handleChangePasswordEvent(ChangePasswordEvent event) {
logger.info("handleChangePasswordEvent for : " + event.getUsername());
List<Object> loggedUsers = sessionRegistry.getAllPrincipals();
logger.info("loggedUsers : " + loggedUsers.size());
for (Object principal : loggedUsers) {
if (principal instanceof User) {
final User loggedUser = (User) principal;
logger.info("loggedUser : " + loggedUser.getUsername());
if (event.getUsername().equals(loggedUser.getUsername())) {
List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false);
if (null != sessionsInfo && sessionsInfo.size() > 0) {
for (SessionInformation sessionInformation : sessionsInfo) {
logger.info("Exprire now :" + sessionInformation.getSessionId());
sessionInformation.expireNow();
sessionRegistry.removeSessionInformation(sessionInformation.getSessionId());
// User is not forced to re-logging
}
}
}
}
}
}
}
The listener works fine, the problem is that the list of authenticated users that returns me sessionRegistry is empty.
I've tried all the solutions I've seen for the same problem and they have not worked for me.
Here I put all the configuration of Spring Security.
#Configuration
#EnableGlobalMethodSecurity(securedEnabled = true)
#EnableWebSecurity
#ComponentScan(value = { "security" })
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private CustomLogoutHandler logoutHandler;
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationEventPublisher(authenticationEventPublisher())
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Bean
public DefaultAuthenticationEventPublisher authenticationEventPublisher() {
return new DefaultAuthenticationEventPublisher();
}
/**
* Security Configuration for Admin zone
*/
#Configuration
#Order(1)
public class AdminConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationSuccessHandler successHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**")
.hasAuthority(AuthorityEnum.ROLE_ADMIN.name())
.and()
.formLogin()
.loginPage("/admin/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler)
.permitAll()
.and()
.logout()
.addLogoutHandler(logoutHandler)
.logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout"))
.logoutSuccessUrl("/admin/login?logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf()
.disable();
}
}
/**
* Security Configuration for Frontend zone
*/
#Configuration
#Order(2)
public class FrontendConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/*.*")
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.addLogoutHandler(logoutHandler)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf();
}
}
#Configuration
#Order(3)
public class GlobalWebConfiguration extends WebSecurityConfigurerAdapter {
private SessionRegistry sessionRegistry;
#Autowired
private MessageSource messageSource;
#Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionAuthenticationStrategy(compositeSessionAuthenticationStrategy())
.sessionFixation()
.changeSessionId()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.expiredUrl("/login?expired")
.sessionRegistry(sessionRegistry())
.and()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/");
// Here we protect site from:
// 1. X-Content-Type-Options
http.headers().contentTypeOptions();
// 2. Web Browser XSS Protection
http.headers().xssProtection();
http.headers().cacheControl();
http.headers().httpStrictTransportSecurity();
// 3. X-Frame-Options
http.headers().frameOptions();
}
#Bean
public SessionRegistry sessionRegistry() {
if (sessionRegistry == null) {
sessionRegistry = new SessionRegistryImpl();
}
return sessionRegistry;
}
#Bean
#Order(1)
public ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy() {
ConcurrentSessionControlAuthenticationStrategy strategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
strategy.setExceptionIfMaximumExceeded(true);
strategy.setMessageSource(messageSource);
return strategy;
}
#Bean
#Order(2)
public SessionFixationProtectionStrategy sessionFixationProtectionStrategy(){
return new SessionFixationProtectionStrategy();
}
#Bean
#Order(3)
public RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy(){
RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy = new RegisterSessionAuthenticationStrategy(sessionRegistry());
return registerSessionAuthenticationStrategy;
}
#Bean
public CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy(){
List<SessionAuthenticationStrategy> sessionAuthenticationStrategies = new ArrayList<>();
sessionAuthenticationStrategies.add(concurrentSessionControlAuthenticationStrategy());
sessionAuthenticationStrategies.add(sessionFixationProtectionStrategy());
sessionAuthenticationStrategies.add(registerSessionAuthenticationStrategy());
CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy = new CompositeSessionAuthenticationStrategy(sessionAuthenticationStrategies);
return compositeSessionAuthenticationStrategy;
}
}
}
I have a WebSecurityConfigurerAdapter for the admin zone with its own login page and another for normal users.
At the end is GlobalWebConfiguration to configure the session manager for both zones (admin and users).
Hope someone can help me

Spring bcrypt blank password

I'm using Spring Boot webapp with Spring Security. Passwords of my users are stored in my DB after encoding with bcrypt. With some users if I try to login with correct username and blank password (empty string) authentication process not throw exception 401 but return me user as logged in. How is it possible?
This is a part of my code:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
public static final String REMEMBER_ME_KEY = "rememberme_key";
#Autowired
private CustomUserDetailsService userDetailsService;
#Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;
#Autowired
private AccessDeniedHandler restAccessDeniedHandler;
#Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;
#Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;
#Autowired
private RememberMeServices rememberMeServices;
#Autowired
private BCryptPasswordEncoder bcryptEncoder;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bcryptEncoder);
}
#Bean
public AuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter();
authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean());
return authenticationTokenFilter;
}
#Bean
public SwitchUserFilter switchUserFilter() {
SwitchUserFilter filter = new SwitchUserFilter();
filter.setUserDetailsService(userDetailsService);
filter.setUsernameParameter("login");
filter.setSwitchUserUrl("/switch_user");
filter.setExitUserUrl("/switch_user_exit");
filter.setTargetUrl("http://xxxxx.xxxxx.it/resource/api/users/me");
filter.setSwitchFailureUrl("http://xxxxx.xxxxxx.it/resource/version");
return filter;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/switch_user").hasAnyRole("ADMIN", "GOD")
.antMatchers("/switch_user_exit").hasRole("PREVIOUS_ADMINISTRATOR")
.antMatchers("/static/**").permitAll()
.antMatchers("/users").permitAll()
.antMatchers("/version").permitAll()
.antMatchers("/ms3/**").permitAll()
.antMatchers("/form/**").permitAll()
.antMatchers("/extapi/**").permitAll()
.anyRequest().authenticated()
.and()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.accessDeniedHandler(restAccessDeniedHandler)
.and()
.formLogin()
.loginProcessingUrl("/authenticate")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.deleteCookies("JSESSIONID")
.permitAll().and().rememberMe()
.rememberMeServices(rememberMeServices)
.key(REMEMBER_ME_KEY)
.and().addFilterAfter(switchUserFilter(), FilterSecurityInterceptor.class);
http
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bcryptEncoder);
}
}

Authorization roles Spring-boot Oauth2 ~ Restful API

i'm needing help with this problem...
i can't secure my controllers in my security configuration files. but i can do it in my controller using
#PreAuthorize("hasAuthority('ROLE_ADMIN')")
but this is really annoying, i want to do it from my security conf. files
this is my WebSecurityconfigurerAdapter:
#Configuration
//#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = false)
//#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
//#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
CustomAuthenticationProvider customAuthenticationProvider;
#Autowired
CustomUserDetailsService cuds;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(cuds)
.passwordEncoder(passwordEncoder())
.and()
.authenticationProvider(customAuthenticationProvider);
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").authenticated()
.antMatchers("/test").authenticated()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
}
and this is my Oauth2Configuration:
#Configuration
public class Oauth2Configuration {
private static final String RESOURCE_ID = "restservice";
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Autowired
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
// Logout
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
//Session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//URI's to verify
.authorizeRequests()
.antMatchers("/oauth/logout").permitAll()
.antMatchers("/**").authenticated()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
}
i've tried to use authority and roles, but nothings works. some idea what i'm doing wrong?
Well thanks to Yannic Klem i got the answer, was a problem with the order
First on my WebSecurityConfigurerAdapter i set my authentication on "usuarios"
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/usuarios").authenticated();
}
after that in my Oauth2Configuration set my authorizarion with my rol.
#Override
public void configure(HttpSecurity http) throws Exception {
http
// Logout
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
//Session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//URI's to verify
.authorizeRequests()
.antMatchers("/oauth/logout").permitAll()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
and now all works pretty fine. thank you all!

Redirect in a filter with Spring Boot

In my configuration Spring Boot WebSecurityConfig have a filter that I need to see if the user has the expired password, if it is enabled on the application ..
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
IdentityService userDetailsService;
#Autowired
AccountFilter accountFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.and()
.authorizeRequests()
.antMatchers("/login", "/recover-credntial",
"/logout", "/resources/**").permitAll()
.and()
.formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and().addFilterAfter(accountFilter, UsernamePasswordAuthenticationFilter.class);
}
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder)
throws Exception {
authManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
As you see I have .and().addFilterAfter(Account Filter, UsernamePasswordAuthenticationFilter.class); in the HTTP configuration.
How do I define my filter so that it can perform a redirect to the URL of some of my controller?
I'm using in Java Web Application 'Spring Boot' with Java Configuration, not file xml!
One approach would be as follows using ExceptionMappingAuthenticationFailureHandler. This will mean not using the servlet though.
Configuration
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.failureHandler(authenticationFailureHandler())
.and()
.logout()
.permitAll();
}
Authentication Failure Handler
#Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
ExceptionMappingAuthenticationFailureHandler exceptionMappingAuthenticationFailureHandler = new ExceptionMappingAuthenticationFailureHandler();
Map<String, String> exMap = new HashMap<String, String>();
exMap.put("org.springframework.security.authentication.CredentialsExpiredException","/loginerror/credentialsexpired.htm");
exceptionMappingAuthenticationFailureHandler.setExceptionMappings(exMap);
return exceptionMappingAuthenticationFailureHandler;
}
Custom User Details Service
#Service
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// Check if Password Expired then throw
throw new CredentialsExpiredException("Expired");
}
}

Resources