使用 Spring Boot 在过滤器中重定向

Redirect in a filter with Spring Boot

在我的配置中 Spring Boot WebSecurityConfig 有一个过滤器,如果在应用程序上启用它,我需要查看用户是否有过期密码..

@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;
    }

}

如您所见,我在 HTTP 配置中有 .and().addFilterAfter(Account Filter, UsernamePasswordAuthenticationFilter.class);
如何定义我的过滤器,以便它可以执行重定向到我的某些控制器的 URL? 我在 Java Web 应用程序 'Spring Boot' 中使用 Java 配置,而不是文件 xml!

一种方法如下,使用 ExceptionMappingAuthenticationFailureHandler。这将意味着不使用 servlet。

配置

@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();
    }

身份验证失败处理程序

 @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;
    }

自定义用户详细信息服务

@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");
    }

}