2017-12-10 12 views
0

JSON 로그인 페이로드를 허용하도록 Spring Security를 ​​구성하려고합니다. 그러나 UsernamePasswordAuthenticationFilter을 사용자 정의 필터로 사용하면 부작용으로 스프링 보안이 AuthenticationSuccessHandler을 예상대로 수행하지 못하고 스프링 리디렉션 요청을 루트 페이지 (기본 스프링 보안 설정)에 전달하게됩니다.UsernamePasswordAuthenticationFilter AuthenticationSuccessHandler를 무시하십시오.

참고 : 나는 구성에서, 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; 
     } 
    } 

답변

0

당신은 호출 할 수 있습니다 귀하의 인증을 사용자 정의하는 방법 setAuthenticationSuccessHandler 고사. setAuthenticationSuccessHandler()은 추상 클래스 AbstractAuthenticationProcessingFilter으로 정의됩니다.

+0

이'AbstractAuthenticationProcessingFilter'이 할 수있는 간단한 방법이있다, 방법의 톤을 구현 필요 확장? 어쩌면 기존의'successHandler' ('SimpleUrlAuthenticationSuccessHandler') 등으로 링크하고 있을까요? – XPLOT1ON

+0

UsernamePasswordAuthenticationFilter는 이미 AbstractAuthenticationProcessingFilter를 확장합니다. UsernamePasswordAuthenticationFilter를 이미 사용하고 있다면 setAuthenticationSuccessHandler를 customHandler로 호출 할 수 있습니다. 필요한 경우 SimpleUrlAuthenticationSuccessHandler를 사용할 수 있습니다. – Persia

+0

@ XPLOT1ON'AbstractAuthenticationProcessingFilter'를 확장하면 이미 가지고있는 하나의 단일 메소드를 구현해야합니다. –

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

추가하여 JsonauthenticationFilterBasicAuthenticationFilter 전과 :

protected void configure(HttpSecurity httpSecurity) throws Exception { 
    httpSecurity.addFilterBefore(authenticationFilter(), BasicAuthenticationFilter.class); 
    ... 
} 
+0

당신이 말했듯이'IllegalArgumentException : authenticationManager를 지정해야합니다. ' 나는'BasicAuthenticationFilter.class' 파일을'UsernamePasswordAuthenticationFilter.class' 파일로 변경했습니다. – XPLOT1ON

+0

대기, 위의 예외를 더 이상 throw하지 않습니다. 그러나, 그것은'AuthenticationProvider'로 사용자를 인증하지 않습니다. 그것은'successHandler'에 곧바로갔습니다. – XPLOT1ON