Spring+Tomcat应用激活URL触发RequestRejectedException问题求助
核心问题根源
你的问题是UrlRewrite规则的正则表达式错误使用了HTML实体&,导致URL重写过程中将原始参数分隔符&转换为&,而&包含的分号;触发了Spring Security防火墙的恶意字符拦截,抛出RequestRejectedException。隐私窗口因无缓存,首次请求必触发重写规则,刷新后浏览器可能直接访问重定向后的目标URL,因此恢复正常。
具体修复步骤
修正UrlRewrite规则的正则表达式
将<from>标签中的&替换为原始URL参数分隔符&——正则匹配的是URL中的原始字符,而非HTML转义后的实体。修改后的规则如下:<rule> <name>RULE: redirect security urls to index</name> <from>/(forgot-password|forgot-username|activate-account|reset-password|signout|locked-account|sso-error|ird-access-token)([\?\&=a-z0-9-]*)</from> <to last="true">/security/index.zul?function=$1</to> </rule>该修正会让UrlRewrite正确匹配URL中的
&,避免将其转换为&,从根源杜绝分号;进入请求URL。验证Freemarker模板的URL生成逻辑
检查生成激活URL的Freemarker模板,确保模板没有自动转义&为&。若模板中使用变量输出URL,需用?no_esc过滤器禁用转义,示例:<a href="${activationUrl?no_esc}">激活账户</a>这一步是为了从源头保证生成的激活URL参数分隔符为原始
&,而非转义后的实体。(可选)调整Spring Security防火墙规则(不推荐优先使用)
若上述两步修复后仍有问题,可临时调整Spring Security防火墙配置,允许分号;作为合法字符,但这会降低安全性,仅建议作为临时排查手段:@Bean public HttpFirewall allowSemicolonHttpFirewall() { StrictHttpFirewall firewall = new StrictHttpFirewall(); firewall.setAllowSemicolon(true); return firewall; }注意:优先通过修复URL生成和重写逻辑解决问题,而非放宽安全规则。
隐私窗口复现原因说明
隐私窗口默认禁用浏览器缓存,首次点击激活URL时会触发完整的UrlRewrite重定向流程,错误的正则会生成包含&的URL,触发拦截;刷新后,浏览器可能直接访问重定向后的/security/index.zul(或缓存了正确的重定向结果),绕开了错误的重写逻辑,因此页面正常加载。
内容的提问来源于stack exchange,提问作者DelphyM

