【问题标题】:Use AbstractAuthenticationProcessingFilter for multiple URLs对多个 URL 使用 AbstractAuthenticationProcessingFilter
【发布时间】:2018-04-04 14:30:05
【问题描述】:

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

  1. /token -- 所有人都可以访问
  2. /rest/securedone/** -- 需要身份验证
  3. /rest/securedtwo/** -- 需要身份验证
  4. /rest/unsecured/** -- 不需要身份验证

到目前为止,我可以访问 /token 端点。 但是 /rest/securedone/** 和 /rest/unsecured/** 在未发送令牌(JWT)时返回 401。我的意图是保护 /rest/securedone/**,这很好 /rest/unsecured/** 应该可以访问。

我的 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/**,我怎样才能让我的 MyAuthenticationTokenFilter/api/secured/** 请求调用?我不需要不同的身份验证处理,所以我想重用这个过滤器。

【问题讨论】:

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


    【解决方案1】:

    什么时候使用 MyAuthenticationTokenFilter ?

    此过滤器用于处理带有客户端凭据的请求,当 RequestMatcher与请求url匹配时,它将过滤url,例如,在您的配置中,它将处理与/rest/**匹配的url,然后尝试要将客户端凭据转换为Authentication(例如 userInfo、role ...),当请求的客户端凭据不正确时,它可能会引发异常。 与authorizeRequests(xxx.authenticated()xxx.permit())不同,authorizeRequests只检查身份验证是否有一些特殊属性(例如角色,范围)。

    打个比方,AbstractAuthenticationProcessingFilter 只是将一些卡片(Authentication)放入不同客户的盒子(SecurityContext)中,authorizeRequests 只需勾选盒子有它需要的卡片,否则它会拒绝请求。 AbstractAuthenticationProcessingFilter 不在乎谁/如何使用卡片,authorizeRequests 不在乎卡片来自哪里。

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

    是的,您可以通过setRequiresAuthenticationRequestMatcher 设置requiresAuthenticationRequestMatcher,例如,它将覆盖旧的requiresAuthenticationRequestMatcher

    authenticationTokenFilter
        .setRequiresAuthenticationRequestMatcher(new OrRequestMatcher(                                                                                     
            new AntPathRequestMatcher("/rest/secured/**")                                                                                   
            , new AntPathRequestMatcher("/api/secured/**")                                                                            
         ));
    

    【讨论】:

    • 非常感谢您的简化解释和您的时间。我想我现在对它的理解更加巩固了。
    猜你喜欢
    • 2017-10-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多