Spring Security根路径绕过及URL权限配置异常技术咨询
嘿,刚接触Spring Security就碰到这种权限绕过的坑确实闹心!我来帮你拆解一下问题根源,再给你对应的解决方案。
首先,先明确你的场景:你用XML配置了如下权限规则:
<filter-invocation-definition-source id="objectDefinitionSource"> <intercept-url pattern="/oneLink/**" access="admin"/> </filter-invocation-definition-source>
访问localhost:8080/oneLink会正常跳转到登录页,但加个?变成localhost:8080/oneLink?就能直接访问;另外根路径用非/的特殊字符也能绕过权限校验。这本质上是Spring Security默认URL匹配策略的宽松性导致的。
问题根源
- AntPathMatcher的匹配细节:你用的
/oneLink/**模式,虽然理论上应该匹配/oneLink及其所有子路径,但在部分Spring Security版本中,带查询参数的/oneLink?可能因为路径解析的优先级问题,被后续更宽泛的规则(比如/**)优先匹配到,从而绕过了权限校验。 - 特殊字符的路径解析:Servlet容器默认允许像
/;、/,这类带特殊字符的路径,而Spring Security默认的匹配器不会拦截这些变体,导致根路径的权限规则被绕过。
解决方案
1. 明确覆盖所有URL变体
先调整你的intercept-url配置,把/oneLink本身的规则单独列出来,放在/oneLink/**前面,确保优先匹配:
<filter-invocation-definition-source id="objectDefinitionSource"> <!-- 优先匹配/oneLink本身(包括带查询参数的情况) --> <intercept-url pattern="/oneLink" access="admin"/> <!-- 匹配/oneLink下的所有子路径 --> <intercept-url pattern="/oneLink/**" access="admin"/> <!-- 其他公开路径规则放在中间 --> <intercept-url pattern="/public/**" access="permitAll"/> <!-- 最后放兜底的认证规则 --> <intercept-url pattern="/**" access="authenticated"/> </filter-invocation-definition-source>
记住:Spring Security的intercept-url是按顺序匹配的,第一个匹配到的规则生效,所以一定要把严格的、敏感的路径规则放在最前面。
2. 配置严格的路径匹配器
自定义AntPathMatcher,关闭宽松的匹配选项,确保URL的每个细节都被校验:
<!-- 自定义严格的路径匹配器 --> <bean id="strictPathMatcher" class="org.springframework.security.web.util.matcher.AntPathMatcher"> <!-- 禁用后缀匹配(比如/oneLink.html不会被当成/oneLink) --> <property name="useSuffixPatternMatch" value="false"/> <!-- 禁用尾部斜杠匹配(比如/oneLink/不会被当成/oneLink) --> <property name="useTrailingSlashMatch" value="false"/> </bean> <!-- 把自定义匹配器注入到规则源中 --> <filter-invocation-definition-source id="objectDefinitionSource" path-matcher-ref="strictPathMatcher"> <intercept-url pattern="/oneLink" access="admin"/> <intercept-url pattern="/oneLink/**" access="admin"/> <!-- 其他规则 --> </filter-invocation-definition-source>
这样配置后,URL的任何变体(带查询参数、尾部斜杠、后缀)都不会被宽松匹配,必须严格符合你定义的模式。
3. 解决特殊字符绕过根路径的问题
针对根路径用特殊字符绕过的情况,有两种靠谱的解决方式:
- 配置Servlet容器:比如在Tomcat的
server.xml里,给Connector添加allowPathInfo="false",禁止解析这类特殊路径; - 自定义拦截过滤器:写一个简单的过滤器,提前检查请求路径是否包含特殊字符,如果是直接返回403禁止访问,或者重定向到登录页。
如果不想动容器配置,也可以临时添加覆盖特殊路径的规则,但这种方式比较繁琐,适合临时应急:
<!-- 拦截根路径的特殊变体 --> <intercept-url pattern="/;" access="authenticated"/> <intercept-url pattern="/," access="authenticated"/> <intercept-url pattern="/?" access="authenticated"/> <!-- 其他特殊字符路径 -->
4. 升级Spring Security版本
如果你的Spring Security版本比较旧(比如4.x及以下),这些URL匹配的安全问题在新版本(5.x以上)中已经被修复了。升级到最新的稳定版本,能从根源上减少这类绕过风险。
总结
核心思路就是收紧URL匹配规则,确保所有可能的请求变体都被覆盖,同时利用Spring Security的规则匹配优先级,把敏感路径的规则放在最前面。按照上面的步骤调整后,这些权限绕过的问题就能解决啦!
内容的提问来源于stack exchange,提问作者swetha

