问题
shiro从1.9升级到1.11后登录页出现循环重定向,打开登录页后会出现:ERR_TOO_MANY_REDIRECTS
排查
在AdviceFilter打断点,发现处理request时,/login处理后,/WEB-INF/jsp/login.jsp 也会进来过滤链,导致jsp页面被拦截,又被重定向到/login。
在ShiroFilter上跟踪发现,对比1.9和1.11的处理流程,发现多了一个filterOncePerRequest属性,这个属性默认为false,导致一次请求被重复处理了多次。
/**
* Determines if the filter's once per request functionality is enabled, defaults to false. It is recommended
* to leave this disabled if you are using a {@link javax.servlet.RequestDispatcher RequestDispatcher} to forward
* or include request (JSP tags, programmatically, or via a framework).
*/
private boolean filterOncePerRequest = false;
.....
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
if ( request.getAttribute(alreadyFilteredAttributeName) != null && filterOncePerRequest) {
log.trace("Filter '{}' already executed. Proceeding without invoking this filter.", getName());
filterChain.doFilter(request, response);
} else //noinspection deprecation
...
}
这是shiro为了修复身份验证绕过漏洞添加,shiro.apache.org/blog/2022/1…
文档里也说明了这个问题:
行为变化
从 1.10.0 开始,Shiro 可能会多次过滤请求,例如在包含或转发请求时。 可以通过设置以下属性来恢复此行为:
shiro.filterOncePerRequest=true
解决:
配置匿名访问规则 /WEB-INF/jsp/login.jsp=anon,让shiro跳过login.jsp的验证。
当然可以通过设置shiro.filterOncePerRequest=true来实现,但是这样会有绕过身份认证漏洞的问题。