春季启动中的自定义成功处理程序

时间:2018-03-12 10:50:01

标签: java spring-boot spring-security jwt

我按照教程https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/将jwt集成到我的应用程序中。我正在尝试将自定义successhandler添加到我的应用程序中。不幸的是,成功的登录请求不会触发successhandler。我尝试返回一个用户对象,而不是在标头中使用令牌进行空响应。我的处理程序是

@Component
public class AuthSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    private ApplicationUserRepository userRepository;
    @Autowired
    private ObjectMapper objectMapper;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        UserDetails user = (UserDetails) authentication.getPrincipal();
        AuthInfo authInfo = new AuthInfo();
        authInfo.setUser(userRepository.findOneByUserName(user.getUsername()));
        authInfo.setToken(response.getHeader("Authentication"));
        response.getWriter().write(objectMapper.writeValueAsString(authInfo));
        response.setContentType("application/json");
        response.setStatus(200);
    }

}

我已在WebSecurityConfigurer.configure()中将其配置为

protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable().authorizeRequests()
            .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
            .antMatchers(HttpMethod.GET, "/public/**").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .successHandler(successHandler)
            .and()
            .addFilter(new JWTAuthenticationFilter(authenticationManager(), securityConfig))
            .addFilter(new JWTAuthorizationFilter(authenticationManager(), securityConfig))
            // this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

@ pvpkiran的解决方案并没有奏效。在调试时,我发现authenticationfilter正在运行两次,并且授权过滤器没有触发。下面给出了应用程序日志中可用的过滤器列表

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  CorsFilter
  LogoutFilter
  JWTAuthenticationFilter
  JWTAuthorizationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

1 个答案:

答案 0 :(得分:0)

试试这个。创建这样的本地方法。

 public JwtAuthenticationTokenFilter authenticationTokenFilter() {
        JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
        filter.setAuthenticationManager(authenticationManager());
        filter.setAuthenticationSuccessHandler(successHandler);
        return filter;
    }

然后像这样更改配置方法

protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable().authorizeRequests()
            .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
            .antMatchers(HttpMethod.GET, "/public/**").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

另一点是,最好不要让你的AuthSuccessHandler bean(删除@Component)并在你的安全配置中创建一个像这样的AuthSucessHandler对象。原因是,如果您将AuthSuccessHandler声明为bean,则spring将扫描它并添加两个SuccessHandler(
 1.扫描豆子时,
 2.在SecurityConfig中添加它时 )

@EnableWebSecurity
@Configuration
public class JwtSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ApplicationUserRepository userRepository;
    @Autowired
    private ObjectMapper objectMapper;

    public JwtAuthenticationTokenFilter authenticationTokenFilter() {
        JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
        filter.setAuthenticationManager(authenticationManager());
        AuthSuccessHandler successHandler = new AuthSuccessHandler(userRepository, objectMapper):
        filter.setAuthenticationSuccessHandler(successHandler);
        return filter;
    }


protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable().authorizeRequests()
            .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
            .antMatchers(HttpMethod.GET, "/public/**").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

像这样更改您的AuthSuccessHandler

public class AuthSuccessHandler implements AuthenticationSuccessHandler {
    private ApplicationUserRepository userRepository;
    private ObjectMapper objectMapper;

    public AuthSuccessHandler(ApplicationUserRepository userRepository, ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        this.userRepository = userRepository;
    }

    ........
 }