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

Spring Security结合JWT时Ant Matcher未按指定角色限制端点权限的问题排查

问题分析与解决方案

首先,你的问题核心在于Spring Security的antMatchers使用了正则表达式路径,但antMatchers实际上是基于Ant风格路径模式匹配的,而非正则表达式。这导致你配置的角色权限规则根本没有匹配到对应的请求路径,所有已认证用户都会通过anyRequest().authenticated()的规则被允许访问,完全绕过了你设置的角色权限校验。

具体修正步骤

1. 修正路径匹配规则

你有两种可选的修正方式:

方式一:改用Ant风格路径匹配

把配置中的正则路径替换为Ant风格路径,这是antMatchers的标准用法:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/login", "/users/**").permitAll()
        // 使用Ant风格的*匹配单个ID路径段
        .antMatchers(PUT, "/answers/*").hasAnyAuthority("ROLE_INSTRUCTOR")
        .antMatchers(GET, "/answers/*/is-correct").hasAnyAuthority("ROLE_STUDENT")
        .anyRequest().authenticated()
        .and()
        .addFilter(new CustomAuthenticationFilter(authenticationManagerBean()))
        .addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .csrf().disable();
}

方式二:改用regexMatchers适配正则路径

如果你需要精确匹配数字ID的路径,可以使用regexMatchers替代antMatchers,保留你的正则表达式:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/login", "/users/**").permitAll()
        // 使用regexMatchers支持正则表达式路径
        .regexMatchers(PUT, "/answers/(\\d+)").hasAnyAuthority("ROLE_INSTRUCTOR")
        .regexMatchers(GET, "/answers/(\\d+)/is-correct").hasAnyAuthority("ROLE_STUDENT")
        .anyRequest().authenticated()
        .and()
        .addFilter(new CustomAuthenticationFilter(authenticationManagerBean()))
        .addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .csrf().disable();
}

2. 可选:简化权限配置写法

如果你的角色都是以ROLE_前缀开头,可以使用hasRole替代hasAnyAuthority,这样不用写完整的ROLE_XXX字符串:

.antMatchers(PUT, "/answers/*").hasRole("INSTRUCTOR")
.antMatchers(GET, "/answers/*/is-correct").hasRole("STUDENT")

(hasRole会自动在角色名前添加ROLE_前缀,所以这里只需要写INSTRUCTOR而非ROLE_INSTRUCTOR)

3. 验证权限注入正确性

你的CustomAuthorizationFilter中权限注入逻辑是正确的,但可以加一行日志确认权限是否正确加载:

// 在CustomAuthorizationFilter的权限处理代码中添加
log.info("User {} is granted with authorities: {}", username, authorities);

为什么原配置不生效?

Spring Security的antMatchers遵循Ant路径语法规则:

  • * 匹配任意非路径分隔符的字符
  • ** 匹配任意字符(包括路径分隔符/)
  • ? 匹配单个字符

你写的/answers/(\\d+)是正则表达式格式,antMatchers无法识别这种语法,导致对应的权限规则从未被触发,所有已认证用户都落入了anyRequest().authenticated()的规则范围,自然会出现角色越权访问的情况。

内容的提问来源于stack exchange,提问作者Dolphy the Reaper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:53:11