对多个URL使用AbstractAuthenticationProcessingFilter

wor*_*ter 2 authentication rest spring spring-security spring-boot

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

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

截至目前,我能够访问/ 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();
}
Run Code Online (Sandbox Code Playgroud)

我的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);
}
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我弄清楚如下:

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

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

cha*_*luo 6

何时使用MyAuthenticationTokenFilter?

此过滤器用于处理具有客户端凭据的请求,它将在 RequestMatcher匹配请求URL时过滤URL,例如,在您的配置中,它将处理匹配的URL /rest/**,并尝试将客户端凭据转换为Authentication(例如userInfo) ,角色...),它可能会在请求具有不正确的客户端凭据时抛出异常.它与authorizeRequests(xxx.authenticated()xxx.permit())不同,authorizeRequests只需检查身份验证是否具有某些特殊属性(例如角色,范围).

通过类比,AbstractAuthenticationProcessingFilter只需将一些卡片(Authentication)放入SecurityContext不同客户的盒子()中,authorizeRequests只需选中复选框即可获得所需的卡片,否则它将拒绝该请求.AbstractAuthenticationProcessingFilter 不关心谁/如何使用卡,authorizeRequests并不关心卡的来源.

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

是的,你可以设置requiresAuthenticationRequestMatcherby setRequiresAuthenticationRequestMatcher,它会覆盖旧的requiresAuthenticationRequestMatcher,例如,

authenticationTokenFilter
    .setRequiresAuthenticationRequestMatcher(new OrRequestMatcher(                                                                                     
        new AntPathRequestMatcher("/rest/secured/**")                                                                                   
        , new AntPathRequestMatcher("/api/secured/**")                                                                            
     ));
Run Code Online (Sandbox Code Playgroud)