WebSecurity忽略不适用于AbstractAuthenticationProcessingFilter

时间:2019-04-12 16:25:40

标签: java spring spring-boot spring-security jwt

我创建了一个过滤器,在过滤器超级构造函数中,它需要一个defaultFilterProcessesUrl。我通过网址/v1/**选择了所有请求。

我需要不登录/v1/usersPOST方法)和/v1/users/signinPOST方法),但是过滤器不允许。如何解决这个问题?

JWT过滤器:

public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {

    public JwtAuthenticationTokenFilter() {
        super("/v1/**");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

         String header = request.getHeader("Authorization");
         if(header == null || !header.startsWith("Bearer")){
             throw new RuntimeException("JWT token is missing");
         }

         String authenticationToken = header.substring(7);

        JwtAuthenticationToken token = new JwtAuthenticationToken(authenticationToken);
        return getAuthenticationManager().authenticate(token);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);
        chain.doFilter(request, response);
    }
}

Spring Security配置:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationProvider authenticationProvider;
    @Autowired
    private JwtAuthenticationEntryPoint entryPoint;

    @Bean
    public AuthenticationManager authenticationManager(){
        return new ProviderManager(Collections.singletonList(authenticationProvider));
    }

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

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
                .antMatchers(HttpMethod.POST, "/v1/users")
                .antMatchers(HttpMethod.POST, "/v1/users/signin")
                .antMatchers(HttpMethod.POST, "/token");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
             .csrf().disable()
             .authorizeRequests()
                .anyRequest().hasAnyRole("SG_ADMIN", "O_ADMIN", "OS_ADMIN")
                .and()
             .exceptionHandling().authenticationEntryPoint(entryPoint)
                .and()
             .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

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

1 个答案:

答案 0 :(得分:0)

您可以将其他构造函数与RequestMatcher一起使用,请参见AbstractAuthenticationProcessingFilter

  

AbstractAuthenticationProcessingFilter

     

protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher)

     

创建一个新实例

     

参数:

     

requiresAuthenticationRequestMatcher-用于确定是否需要认证的RequestMatcher。不能为空。

您修改的代码:

public JwtAuthenticationTokenFilter() {
    super(customRequestMatcher);
}

 RequestMatcher customRequestMatcher = new AndRequestMatcher(
      new AntPathRequestMatcher("/v1/**"), 
      new NegatedRequestMatcher(
          new AntPathRequestMatcher("/v1/users", "POST")
      ),
      new NegatedRequestMatcher(
          new AntPathRequestMatcher("/v1/users/signin", "POST")
      )
 );