UsernamePasswordAuthenticationFilter忽略AuthenticationSuccessHandler

时间:2017-12-10 21:59:10

标签: spring spring-security

我正在尝试将Spring Security配置为接受JSON登录有效负载。但是,使用UsernamePasswordAuthenticationFilter作为自定义过滤器的副作用导致Spring Security不按预期方式跟随AuthenticationSuccessHandler,而是将重定向请求弹出到根页面(默认的spring security config)。

注意:如果我从配置中移除addFilterAt并使用FORM URL ENCODED登录,则会按预期跟随AuthenticationSuccessHandler

WebSecurityConfigurer

http
        .authorizeRequests()
        .antMatchers(permitURI).permitAll()
        .anyRequest().authenticated()
        .and()
        .addFilterAt(new JSONAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        .formLogin().loginProcessingUrl("/login")
        .successHandler(authSuccess).failureHandler(authFailure).permitAll()
        .and()
        .exceptionHandling().authenticationEntryPoint(authEntry)
        .and()
        .rememberMe().rememberMeCookieName("AUTOLOGIN")
        .and()
        .cors()
        .and()
        .logout().logoutUrl("/logout").permitAll()
        .clearAuthentication(true)
        .invalidateHttpSession(true)
        .deleteCookies("JSESSIONID", "AUTOLOGIN")
        .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
        .permitAll();

http.csrf().disable();

UsernamePasswordAuthenticationFilter

@Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        String payload;
        try {
            ObjectMapper mapper = new ObjectMapper();
            payload = IOUtils.toString(request.getInputStream(), Charset.defaultCharset());
            JsonAuthenticationParser auth = mapper.readValue(payload, JsonAuthenticationParser.class);

            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(auth.getUsername(), auth.getPassword());

            return authRequest;
        } catch (IOException e) {
            throw new InternalAuthenticationServiceException(e.getMessage(), e);
        }
    }

    static class JsonAuthenticationParser {
        private final String username;
        private final String password;

        @JsonCreator
        public JsonAuthenticationParser(@JsonProperty("username") String username, @JsonProperty("password") String password) {
            this.username = username;
            this.password = password;
        }

        public String getUsername() {
            return username;
        }

        public String getPassword() {
            return password;
        }
    }

2 个答案:

答案 0 :(得分:0)

您可以调用setAuthenticationSuccessHandler方法来自定义身份验证成功操作。 setAuthenticationSuccessHandler()在抽象类AbstractAuthenticationProcessingFilter中定义。

答案 1 :(得分:0)

您的JsonAuthenticationFilter看起来很好(我认为它延伸AbstractAuthenticationProcessingFilter)。

尝试以下WebConfig

您应该将LoginSuccessHandler直接添加到JsonAuthenticationFilter

@Bean
public JsonAuthenticationFilter authenticationFilter() throws Exception {
    JsonAuthenticationFilter filter = new JsonAuthenticationFilter();
    filter.setAuthenticationManager(authenticationManagerBean());
    filter.setAuthenticationSuccessHandler(new MyLoginSuccessHandler());
    return filter;
}

JsonauthenticationFilter

之前添加BasicAuthenticationFilter
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.addFilterBefore(authenticationFilter(), BasicAuthenticationFilter.class);
    ...
}