SpringBoot UsernamePasswordAuthenticationFilter问题

Zou*_*zou 3 spring-security spring-boot

我正在扩展,UsernamePasswordAuthenticationFilter以便我可以添加自定义字段以将它们保存到会话中.

public class AuthFilter extends UsernamePasswordAuthenticationFilter {

@Override
public Authentication attemptAuthentication(HttpServletRequest request,
        HttpServletResponse response) throws AuthenticationException {
    //String dbValue = request.getParameter("dbParam");
    //request.getSession().setAttribute("dbValue", dbValue);
    System.out.println("attempting to authentificate");
    while (request.getAttributeNames().hasMoreElements()) {
        String e = (String) request.getAttributeNames().nextElement();
        System.out.println("param name : " + e + " and param value : " + request.getAttribute(e));
    }

    return super.attemptAuthentication(request, response);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有我的WebSecurityConfig

@Configuration
@EnableWebMvcSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;


@Bean
public AuthFilter customUsernamePasswordAuthenticationFilter()
        throws Exception {
    AuthFilter customUsernamePasswordAuthenticationFilter = new AuthFilter();
    customUsernamePasswordAuthenticationFilter
            .setAuthenticationManager(authenticationManagerBean());
   return customUsernamePasswordAuthenticationFilter;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterAfter(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

    http.exceptionHandling().accessDeniedPage("/403").and()
            .authorizeRequests().antMatchers("/login", "/public/**").permitAll()
            .antMatchers("/users/**").hasAuthority("ADMIN")
            .anyRequest()
            .authenticated().and().formLogin().loginPage("/login")
            .defaultSuccessUrl("/index").permitAll().and().logout()
            .permitAll();


    http.sessionManagement().maximumSessions(1)
            .expiredUrl("/login?expired").and()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            .invalidSessionUrl("/");
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws  Exception {
    auth.eraseCredentials(false)
    .userDetailsService(userDetailsService);
}
Run Code Online (Sandbox Code Playgroud)

映射过滤器:'customUsernamePasswordAuthenticationFilter'为:[/*]

所以我肯定知道过滤器是正确添加的,但是我永远不能打印出内部的内容,因此在验证过程中不会调用它.

我使用Thymeleaf而没有xml配置.

作为@M.Deinum的建议,我改变了我UsernamePasswordAuthenticationFilter,对AbstractAuthenticationProcessingFilter,叫super(new AntPathRequestMatcher("/login","POST")); addFilterAfteraddFilterBefore和一些代码,和它的工作!

M. *_*num 9

假设您使用的是最新的Spring Boot(1.2.3),那么您使用的是Spring Security 3.2.7.此版本映射UsernamePasswordAuthenticationFilter/j_spring_security_check.但是,当使用基于java的配置时,这将更改为/login.

您的仍然映射到旧URL.要修复此扩展,请AbstractAuthenticationProcessingFilter添加一个默认的no-args构造函数,该构造函数调用带有a的超级构造函数RequestMatcher.这样做的缺点是,如果您仍然需要(或想要扩展)功能,则UsernamePasswordAuthenticationFilter必须复制它.

public AuthFilter() {
    super(new AntPathRequestMatcher("/login","POST"));
}
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是仍然从那里扩展UsernamePasswordAuthenticationFilter和调用setRequiresAuthenticationRequestMatcher.

public AuthFilter() {
    super();
    setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST"));
}
Run Code Online (Sandbox Code Playgroud)

或者从工厂方法中调用该方法.

@Bean
public AuthFilter customUsernamePasswordAuthenticationFilter()
    throws Exception {
    AuthFilter customUsernamePasswordAuthenticationFilter = new AuthFilter();
    customUsernamePasswordAuthenticationFilter
        .setAuthenticationManager(authenticationManagerBean());
    customUsernamePasswordAuthenticationFilter
        .setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST"));
    return customUsernamePasswordAuthenticationFilter;
}
Run Code Online (Sandbox Code Playgroud)

您的配置还有另一个问题,您的过滤器将永远不会被执行,因为它在默认情况下执行UsernamePasswordAuthenticationFilter并且身份验证已经发生,您的过滤器将永远不会执行.确保它在默认过滤器之前执行.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    ...
}
Run Code Online (Sandbox Code Playgroud)