将AbstractAuthenticationProcessingFilter用于多个网址

时间:2017-10-23 22:40:20

标签: spring rest authentication spring-boot spring-security

我的应用程序中有以下端点模式

  1. / token - 所有人都可以访问
  2. / rest / securedone / ** - 需要身份验证
  3. / rest / securedtwo / ** - 需要身份验证
  4. / rest / unsecured / ** - 不需要身份验证
  5. 截至目前,我可以访问/ token端点。 但是/ rest / securedone / **和/ rest / unsecured / **在没有发送令牌(JWT)时返回401。我打算保护/休息/担保/ **,这是好的/休息/不安全/ **应该是可以访问的。

    我的httpSecurity配置如下:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf().disable()
                .authorizeRequests()
                    .antMatchers("/token").permitAll()
                    .antMatchers("/rest/secured/**").authenticated()
                .and()
                .exceptionHandling()
                    .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                    .sessionManagement()
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
        http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    
        http.headers().cacheControl();
    }
    

    和我的AbstractAuthenticationProcessingFilter扩展类如下:

    public class MyAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {
    
    private static Logger log = LoggerFactory.getLogger(MyAuthenticationTokenFilter.class);
    
    public MyAuthenticationTokenFilter() { super("/rest/**");  }
    
    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, ServletException {
        //authentication handling code
    }
    
    
    @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);
    }
    }
    

    有人可以帮我解释下面的内容:

    1. MyAuthenticationTokenFilter何时使用?它将被调用哪个URL?为什么/ rest / unsecured / **也期待身份验证?即使我明确地说.antMatchers(“/ rest / secured / **”)。permitAll()也会发生这种情况。我

    2. 我可以在MyAuthenticationTokenFilter构造函数中的super(defaultFilterProcessingUrl)调用中指定多个url模式吗?例如,如果我有另一个URL,例如/ api / secured / ,我怎样才能为/ api / secured / 请求调用MyAuthenticationTokenFilter?我不需要不同的身份验证处理,因此我想重新使用此过滤器。

1 个答案:

答案 0 :(得分:5)

  

MyAuthenticationTokenFilter何时使用?

此过滤器用于处理带有客户端凭据的请求,它将在 RequestMatcher匹配请求网址时过滤网址,例如,在您的配置中,它将处理与{{1}匹配的网址并尝试将客户端凭据转换为/rest/**(例如userInfo,role ...),它可能会在具有错误客户端凭据的请求时引发异常。 它与AuthenticationauthorizeRequestsxxx.authenticated()),xxx.permit()不同,只需检查身份验证是否具有某些特殊属性(例如角色,范围)。

通过类比,authorizeRequests只是将一些卡片(AbstractAuthenticationProcessingFilter)放入一个框(Authentication)由不同的客户端SecurityContext,只需选中该框就有卡片它需要它,否则它将拒绝该请求。 authorizeRequests  不关心谁/如何使用卡片,AbstractAuthenticationProcessingFilter不关心卡片的来源。

  

我可以在MyAuthenticationTokenFilter构造函数中的super(defaultFilterProcessingUrl)调用中指定多个url模式吗?

是的,您可以按authorizeRequests设置requiresAuthenticationRequestMatcher,它会覆盖旧setRequiresAuthenticationRequestMatcher,例如,

requiresAuthenticationRequestMatcher