使用 JSF 在 Java EE 中开发 Web 应用程序。所有页面都受到保护,无法通过带有操作"j_security_check"和输入"j_username"和"j_password"的身份验证表单进行查看。
但是,成功登录后,我被重定向到的不是我想访问的页面,而是此URL
/faces/javax.faces.resource/jsf.js?ln=javax.faces&stage=Development
所以我正在查看脚本文件 jsf.js其中包含所有 JS 代码而不是我想查看的页面。无论我访问网络根目录还是任何其他页面,我每次都会被重定向到此 URL。然后我将URL更改为任何页面,它可以正常加载并且我已登录。
我不得不说我已经遇到了这个问题,它神奇地消失了,所以它正确地重定向了我。几周后,它又坏了,但我不知道这是否是我的错,如果是,我不知道原因。我根本没有弄乱重定向或导航规则。
值得一提的是,我也在使用PrettyFaces。
编辑:
<security-constraint>
<display-name>secured</display-name>
<web-resource-collection>
<web-resource-name>all</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>admin</role-name>
<role-name>teacher</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>secured for admins</display-name>
<web-resource-collection>
<web-resource-name>admin pages</web-resource-name>
<description/>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>unsecured</display-name>
<web-resource-collection>
<web-resource-name>css</web-resource-name>
<description/>
<url-pattern>/css/*</url-pattern>
</web-resource-collection>
<web-resource-collection>
<web-resource-name>js</web-resource-name>
<description/>
<url-pattern>/js/*</url-pattern>
</web-resource-collection>
<web-resource-collection>
<web-resource-name>img</web-resource-name>
<description/>
<url-pattern>/img/*</url-pattern>
</web-resource-collection>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>wetk-security</realm-name>
<form-login-config>
<form-login-page>/faces/login.xhtml</form-login-page>
<form-error-page>/faces/login.xhtml</form-error-page>
</form-login-config>
</login-config>
容器托管安全性将重定向到触发身份验证检查的最后一个 HTTP 请求。在你的例子中,它显然是自动包含的JSF ajax API JavaScript文件。如果浏览器已完全从浏览器缓存加载待身份验证的页面,而浏览器已完全从服务器端加载JS文件,或者已通过条件GET请求测试了JavaScript文件的缓存有效性,则可能会发生这种情况。
您希望从身份验证检查中排除 JSF 资源(<h:outputScript>
、<h:outputStylesheet>
和<h:graphicImage>
。您可以通过排除通用 URL 模式/javax.faces.resource/*
来做到这一点。您可能只想添加/faces
前缀模式,因为您显然正在使用它而不是*.xhtml
后缀模式。
您还需要指示浏览器不要缓存受限制的页面,以防止浏览器从缓存中加载它(例如,在注销后按后退按钮)。将以下过滤器映射到与您的<security-constraint>
之一相同的 URL 模式上。
@WebFilter("/secured/*") // Use the same URL pattern as <security-constraint>
public class NoCacheFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpRes = (HttpServletResponse) response;
if (!httpReq.getRequestURI().startsWith(httpReq.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
httpRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
httpRes.setHeader("Pragma", "no-cache"); // HTTP 1.0.
httpRes.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(request, response);
}
// ...
}