You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

扩展WebSecurityConfigurerAdapter配置OAuth2资源服务器时,无Authorization令牌请求未被拦截的问题及常规处理方案咨询

这个问题我之前踩过坑!默认的BearerTokenAuthenticationFilter确实会在检测不到令牌时直接放行请求,这就导致那些需要OAuth2认证的路径被匿名请求轻易绕过了。下面给你几种常用的解决办法,按需选择就行:

解决方案1:强制路径认证+配置认证入口点

这是最常用的标准做法,核心是明确要求目标路径必须经过认证,同时配置一个AuthenticationEntryPoint来处理未携带令牌的场景,返回标准的401响应。修改你的Security配置代码:

http.authorizeRequests()
    // 先声明该路径必须认证,优先级高于权限校验
    .mvcMatchers(path).authenticated()
    // 再检查具体的权限要求
    .mvcMatchers(path).hasAnyAuthority(...)
    .and()
    .oauth2ResourceServer()
        .jwt()
        .and()
        // 配置未认证时的响应逻辑
        .authenticationEntryPoint((request, response, authException) -> {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json");
            response.getWriter().write("{\"error\":\"Missing or invalid Authorization header\"}");
        });

这里的.authenticated()是关键——它会告诉Spring Security:访问这个路径的请求必须是已认证的。当请求不带令牌时,Security会触发我们配置的AuthenticationEntryPoint,直接返回401,而不是让请求继续走下去。

解决方案2:自定义过滤器拦截无令牌请求

如果你想直接修改过滤器的行为,不让无令牌请求通过过滤器,可以自定义一个BearerTokenAuthenticationFilter的子类,重写逻辑:

public class CustomBearerAuthFilter extends BearerTokenAuthenticationFilter {

    public CustomBearerAuthFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = this.extractToken(request);
        if (token == null) {
            // 抛出无凭据异常,直接触发认证失败流程
            throw new AuthenticationCredentialsNotFoundException("Authorization header is required");
        }
        // 有令牌的话走原逻辑
        super.doFilterInternal(request, response, filterChain);
    }
}

然后在你的Security配置里替换默认的过滤器:

// 替换默认的BearerTokenAuthenticationFilter
http.addFilterBefore(
        new CustomBearerAuthFilter(authenticationManager()),
        BearerTokenAuthenticationFilter.class
    )
    .authorizeRequests()
        .mvcMatchers(path).hasAnyAuthority(...)
        .and()
    .oauth2ResourceServer().jwt();

这种方式更直接,从过滤器层面就拦截了无令牌请求,不会让请求进入后续的权限校验环节。

解决方案3:使用requiresAuthenticationMatcher(Spring Security 5.4+)

如果你的项目用的是Spring Security 5.4及以上版本,可以用requiresAuthenticationMatcher来指定哪些路径必须触发OAuth2认证,这样过滤器会主动拦截这些路径的无令牌请求:

http.oauth2ResourceServer()
        .jwt()
        .and()
        // 指定需要OAuth2认证的路径
        .requiresAuthenticationMatcher(new AntPathRequestMatcher(path))
    .and()
    .authorizeRequests()
        .mvcMatchers(path).hasAnyAuthority(...);

这个配置会让BearerTokenAuthenticationFilter只对指定路径生效,并且在检测不到令牌时直接触发认证失败,而不是放行请求。


最后补充个小知识点:默认情况下Spring Security会启用匿名认证,所以如果你的路径规则没加.authenticated(),匿名用户会被允许访问。这也是为什么不带令牌的请求能绕过权限校验的原因之一,所以一定要记得给需要认证的路径加上.authenticated()哦。

内容的提问来源于stack exchange,提问作者Albin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:47:33