除了能够使用组件rendered 等面向基于角色的安全性的属性之外,核心JSF 中没有固有的身份验证功能。
默认情况下,JSF 应用程序依赖与包含它的 Web 组件相同的容器管理的安全机制 (JEE5 tutorial)。像Seam 这样的第三方框架可以提供替代方案。
如果您想添加自己的应用程序安全性,servlet filter 是更简单的机制之一。
此过滤器保护restricted 目录下的资源,如web.xml 中所定义:
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>restricted.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/restricted/*</url-pattern>
</filter-mapping>
过滤器类实现:
public class AuthenticationFilter implements Filter {
private FilterConfig config;
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
if (((HttpServletRequest) req).getSession().getAttribute(
AuthenticationBean.AUTH_KEY) == null) {
((HttpServletResponse) resp).sendRedirect("../restricted_login.faces");
} else {
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public void destroy() {
config = null;
}
}
faces-config.xml 中定义的登录 bean:
public class AuthenticationBean {
public static final String AUTH_KEY = "app.user.name";
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public boolean isLoggedIn() {
return FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().get(AUTH_KEY) != null;
}
public String login() {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
AUTH_KEY, name);
return "secret";
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.remove(AUTH_KEY);
return null;
}
}
restricted_login.jsp页面中的JSF登录表单:
<f:view>
<p><a href="restricted/secret.faces">try to go to secret
page</a></p>
<h:form>
Username:
<h:panelGroup rendered="#{not authenticationBean.loggedIn}">
<h:inputText value="#{authenticationBean.name}" />
<h:commandButton value="login"
action="#{authenticationBean.login}" />
</h:panelGroup>
<h:commandButton value="logout"
action="#{authenticationBean.logout}"
rendered="#{authenticationBean.loggedIn}" />
</h:form>
</f:view>
(选择重定向 URL/机制是为了简洁,而不是任何形式的最佳实践;有关更多选项,请参阅 Servlet API。)