使用 Servlet 过滤器和 j_security_check 登录时出现无限循环
Posted
技术标签:
【中文标题】使用 Servlet 过滤器和 j_security_check 登录时出现无限循环【英文标题】:Endless loop when logging in with Servlet Filter and j_security_check 【发布时间】:2017-01-08 09:12:44 【问题描述】:我已经实现了一个 servletFilter 并在我的 web.xml 中声明了它,但问题是我现在无法登录。用户提交他们的用户名和密码,代码重定向到 j_security_check 页面,然后无休止地重新加载 logon.html。在代码 doFilter(req,res) 被命中两次,用于发送回 logon.html 的 sendRedirect 代码从未使用过。
我还缺少另一个元素吗?我读过 servlet 过滤器和 j_security_check 并不总是很好,但我想我可以找到解决方法。
代码:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/logon.html";
String securityURI = request.getContextPath() + "/j_security_check";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean securityRequest = request.getRequestURI().equals(securityURI);
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest || securityRequest)
chain.doFilter(req, res);
else
response.sendRedirect(loginURI);
因此代码会检查请求是来自登录页面还是来自 j_security_check 页面,如果是,则处理 doFilter。这是可行的,但我不确定如果两次都通过,为什么它不处理到应用程序?
web.xml:
<session-config>
<session-timeout>1</session-timeout>
</session-config>
<filter>
<filter-name>servletFilter</filter-name>
<filter-class>org.t.s.w.AuthServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>servletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【问题讨论】:
【参考方案1】:尝试像这样在过滤器中反转您的条件。
if (!loggedIn || !loginRequest || !securityRequest)
response.sendRedirect(loginURI);
else
chain.doFilter(req, res);
【讨论】:
你只是通过反转条件来打破无限循环。【参考方案2】:问题很简单。您的过滤器链正在捕获所有请求,包括对 logon.html 的请求。当过滤器发现用户未登录时,它会重定向到“logon.html”。
“重定向”是一个全新的请求。它向用户的浏览器发送一个响应,告诉它获取一个新的 URL;因此,该新请求将再次点击您的过滤器,一次又一次......一次又一次。
您可以测试请求的 URI 是否为“logon.html”,如果是,则只需“doFilter”,或者进行请求转发。
【讨论】:
以上是关于使用 Servlet 过滤器和 j_security_check 登录时出现无限循环的主要内容,如果未能解决你的问题,请参考以下文章