In previous two posts: Integrating Spring Security 3.1 and JSF 2.0 and Spring Security 3.1 and JSF 2.0 Custom Form”, we integrated Spring Security 3.1 and JSF 2.0.
In this tutorial we will extend the functionality and we will add a logout functionality to our application.
First we will change our secured.xhtml
and add a logout to it.
secured.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> </h:head> <h:body> <h:form> <h:outputLabel value="I am secured, if you are seeing me it means you have logged in correctly, great!"></h:outputLabel> <h:commandLink id="logout" action="#{loginMgmtBean.logout}" value="Logout"></h:commandLink> <h:messages></h:messages> </h:form> </h:body> </html>
Second we will update our LoginBean
to add the logout action method.
LoginBean.java
package com.mumz.jsfspringsec.beans; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.RequestScoped; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; /** * The Class LoginBean. */ @ManagedBean(name="loginMgmtBean") @RequestScoped public class LoginBean { /** The user name. */ private String userName = null; /** The password. */ private String password = null; @ManagedProperty(value="#{authenticationManager}") private AuthenticationManager authenticationManager = null; /** * Login. * * @return the string */ public String login() { try { Authentication request = new UsernamePasswordAuthenticationToken(this.getUserName(), this.getPassword()); Authentication result = authenticationManager.authenticate(request); SecurityContextHolder.getContext().setAuthentication(result); } catch (AuthenticationException e) { e.printStackTrace(); } return "Secured"; } /** * Cancel. * * @return the string */ public String cancel() { return null; } public String logout(){ SecurityContextHolder.clearContext(); return "loggedout"; } public AuthenticationManager getAuthenticationManager() { return authenticationManager; } public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } /** * Gets the user name. * * @return the user name */ public String getUserName() { return userName; } /** * Sets the user name. * * @param userName * the new user name */ public void setUserName(String userName) { this.userName = userName; } /** * Gets the password. * * @return the password */ public String getPassword() { return password; } /** * Sets the password. * * @param password * the new password */ public void setPassword(String password) { this.password = password; } }
Third since we are using JSF 2.0 explicit navigation we will update our faces-config.xml
, to add the navigation for logout.
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> <!-- Enable Spring --> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application> <!-- Simple Navigation Rule --> <!-- If user keys in ToSecure, move to /pages/secure/secured.xhtml--> <!-- Else If user keys in ToUnSecure, move to /pages/unsecure/unsecured.xhtml--> <navigation-rule> <display-name>pages/home/home.xhtml</display-name> <from-view-id>/pages/home/home.xhtml</from-view-id> <navigation-case> <from-action>#{navigator.navigateTo}</from-action> <from-outcome>Secured</from-outcome> <to-view-id>/pages/secure/secured.xhtml</to-view-id> <redirect></redirect> </navigation-case> </navigation-rule> <navigation-rule> <display-name>pages/home/home.xhtml</display-name> <from-view-id>/pages/home/home.xhtml</from-view-id> <navigation-case> <from-action>#{navigator.navigateTo}</from-action> <from-outcome>UnSecured</from-outcome> <to-view-id>/pages/unsecure/unsecured.xhtml</to-view-id> <redirect></redirect> </navigation-case> </navigation-rule> <navigation-rule> <display-name>pages/secure/secured.xhtml</display-name> <from-view-id>/pages/secure/secured.xhtml</from-view-id> <navigation-case> <from-action>#{loginMgmtBean.logout}</from-action> <from-outcome>loggedout</from-outcome> <to-view-id>/pages/home/home.xhtml</to-view-id> <redirect></redirect> </navigation-case> </navigation-rule> <navigation-rule> <display-name>pages/common/login.xhtml</display-name> <from-view-id>/pages/common/login.xhtml</from-view-id> <navigation-case> <from-action>#{loginMgmtBean.login}</from-action> <from-outcome>Secured</from-outcome> <to-view-id>/pages/secure/secured.xhtml</to-view-id> </navigation-case> </navigation-rule> </faces-config>
Final step is to update our jsfspring-sec-security-config.xml
to add the logout functionality.
jsfspring-sec-security-config.xml
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <sec:http auto-config="true" use-expressions="true"> <sec:intercept-url pattern="/pages/secure/**" access="hasRole('ROLE_USER')" /> <sec:intercept-url pattern="/pages/unsecure/**" access="permitAll"/> <sec:intercept-url pattern="/pages/common/**" access="permitAll"/> <sec:intercept-url pattern="/**" access="permitAll"/> <sec:form-login login-page="/pages/common/login.jsf"/> <sec:logout invalidate-session="true" delete-cookies="true" logout-success-url="/"></sec:logout> </sec:http> <sec:authentication-manager alias="authenticationManager"> <sec:authentication-provider> <sec:user-service> <sec:user authorities="ROLE_USER" name="admin" password="admin" /> </sec:user-service> </sec:authentication-provider> </sec:authentication-manager> </beans:beans>
Now deploy and run!
that’s great, but one question, what happens if I hit the browser button back after loggin out, I am able to see the last visited page’s info, it should be redirected to loggin again, how to fix that ? thanks in advance.
It must have been cached by the browser, we can disable caching