使用 Servlet Filter 和 j_security_check 登录时无限循环
Endless loop when logging in with Servlet Filter and j_security_check
我已经实现了一个 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>
尝试像这样在过滤器中反转您的条件。
if (!loggedIn || !loginRequest || !securityRequest) {
response.sendRedirect(loginURI);
} else {
chain.doFilter(req, res);
}
问题很简单。您的过滤器链正在捕获所有请求,包括 logon.html 的请求。当过滤器发现用户未登录时,它会重定向到 "logon.html"。
A "redirect" 是一个全新的请求。它向用户的浏览器发送一个响应,告诉它获取一个新的 URL;因此,这个新请求将一次又一次地击中您的过滤器。
您可以测试请求的 URI 是否为 "logon.html",如果是 "doFilter",或者转发请求。
我已经实现了一个 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>
尝试像这样在过滤器中反转您的条件。
if (!loggedIn || !loginRequest || !securityRequest) {
response.sendRedirect(loginURI);
} else {
chain.doFilter(req, res);
}
问题很简单。您的过滤器链正在捕获所有请求,包括 logon.html 的请求。当过滤器发现用户未登录时,它会重定向到 "logon.html"。
A "redirect" 是一个全新的请求。它向用户的浏览器发送一个响应,告诉它获取一个新的 URL;因此,这个新请求将一次又一次地击中您的过滤器。
您可以测试请求的 URI 是否为 "logon.html",如果是 "doFilter",或者转发请求。