There is no inherent authentication functionality in core JSF beyond being able to use things like component rendered
attributes geared towards role-based security.
By default, a JSF application relies on the same container-managed security mechanisms as the web component that contains it (JEE5 tutorial). 3rd party frameworks like Seam can provide alternatives.
If you want to add your own application security, a servlet filter is one of the simpler mechanisms.
This filter protects resources under the restricted
directory as defined in 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>
The filter class implementation:
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;
}
}
A login bean defined in faces-config.xml
:
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;
}
}
The JSF login form in the restricted_login.jsp
page:
<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>
(The redirect URL/mechanism was chosen for brevity rather than any sort of best practice; see the Servlet API for more options.)