title: Using spring security to reset password when password expired
body: <p>We are building a web application using spring security to protect our app, but we have some problem setting up the logic when userpassword expired. the logic we attempted is </p>
  
  <ol>
  <li>password reset page only accessible if user has certain role</li>
  <li>update the user role in <code>UserDetailsService</code> when we found user passwd expired</li>
  <li>redirect to the pass reset page if <code>CredentialsExpiredException</code> thrown.</li>
  </ol>
  
  <p>we have configured a WebSecurityConfigurerAdapter</p>
  
  <pre><code>public class AuthConfiguration extends WebSecurityConfigurerAdapter {
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
              .antMatchers("/login.jsp").permitAll()
              .antMatchers("/my/**").hasRole("CHANGEPASS")
              .anyRequest().authenticated()
          .and()
            .formLogin()
              .loginPage("/login.jsp")
              .usernameParameter("username")
              .passwordParameter("password")
         .failureHandler(exceptionMappingAuthenticationFailureHandler())
    }
  }
  </code></pre>
  
  <p>and in <em><code>exceptionMappingAuthenticationFailureHandler</code></em> we configured <code>CredentialsExpiredException</code> url to my/changepass.</p>
  
  <p>we also set our <code>UserDetailsService</code> that if we found out that password is expired, assigning the user a new role to "CHANGEPASS"</p>
  
  <pre><code>public class CustomUserDetailsService implements UserDetailsService {
  
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      SystemUser su = userService.getUser(username);
      ...
      if (passExpired) {
          String roles = su.getRole();
          if (!roles.contains("CHANGEPASS")) {
              roles = roles + ",ROLE_CHANGEPASS";
              su.setRole(roles);
              userService.updateUser(su);
          }
      }
  
      return new User(username, su.getPassword(), true, true, 
  }
  </code></pre>
  
  <p>Basing on the request log of the server, we saw when <code>CredentialsExpiredException</code> happens, the request is redirected to my/changepass page, <strong>but it was then redirected to the login page</strong></p>
  
  <p>is there any way access the change pass page when <code>CredentialsExpiredException</code> happens.</p>