Spring Security 3.1.2 with ICEFaces 3.1

Version 8 by Greg Dick
on Sep 07, 2012 15:25.


compared with
Current by Greg Dick
on Sep 07, 2012 15:37.


 
Key
These lines were removed. This word was removed.
These lines were added. This word was added.

View page history


There are 15 changes. View first change.

 h1. Spring Security 3.1.2 and ICEfaces 3.1 Tutorial
  
  
 {attachments:SpringSecurity3IceFaces2-tutoriall.zip}
  
 h3. About Spring Security
  
 Spring Security 3 provides an API for configuring authentication and authorization. Authentication is possible against any number of repositories and databases. Authorization is applied at either the web resource level using Servlet Filters and/or at the business/service method level using aspects and annotations.
  
 h3. About This Tutorial
  
 The purpose of this tutorial is to demonstrate how application developers can use both Spring Security 3.0.7 and ICEfaces 3.0.1 in the same application. Both technologies leverage the Servlet API so it is essential one understands how the various parts of the web.xml file are organized to accommodate both frameworks. Its also important to be mindful that Spring Security is highly configurable. The example below shows only one extension (Session Management). There are several others filters and configuration options your requirements may warrant.
  The purpose of this tutorial is to demonstrate how application developers can use both Spring Security 3.1.2 and ICEfaces 3.1 in the same application. Both technologies leverage the Servlet API so it is essential one understands how the various parts of the web.xml file are organized to accommodate both frameworks. Its also important to be mindful that Spring Security is highly configurable. The example below shows only one extension (Session Management). There are several others filters and configuration options your requirements may warrant. Note that the official Spring-Webflow release has not been updated to fix a problem with overloading methods in the FacesContext that throw UnsupportedOperationExceptions, so the maven Pom included in the tutorial refers to a temporary build location for Spring-Webflow.
  
 
 h3. Tutorial Use Case
  
 The simple business case for this tutorial is a "product documentation" web application. Some of the documentation is publicly available and some of it requires authorization. To satisfy this requirement all content requiring authorization is accessible behind the spring intercept pattern "/secure/*"
  
 h3. Technologies/Libraries Used
  
 This tutorial uses Spring Security 3.1.2, Spring Framework 3.0.6, JSF 2.1.6 and ICEfaces 3.1. The project has been modified to use Maven as the build environment.
  
 h3. Porting from Spring Security 3.0.6 and ICEFaces 3.0.1
  
 In changing from the previous tutorial, users will note the following changes:
  
 1) The *security-config.xml* file will need to name a new up-to-date Spring Security schema as in the following example:
 {code:xml|title=Schema changes}<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-3.1.xsd">
  ...
 </beans:beans>
 {code}
 2) The *SessionManagementFilter* no longer supports an *invalidSessionURL* property. Instead, if so desired, there is a new *SessionManagement* element within the *<http>* element.
  
 {code:xml|title=Session Management} <http>
  ...
  <session-management invalid-session-url="/invalidSession.htm" />
  </http>
 {code}
 With those changes in place, the tutorial operates as it did before.
  
 ----
 {panel}
  
 {panel}Configuration Areas:
  
 # [Configure Your Web.xml For Spring Security|#step1]
 # [Configure Your applicationContext.xml For Spring Security|#step2]
 # [Configure Your Web.xml For JSF|#step3]
 # [Advanced: Configure Your Spring Security redirectStrategy|#step4]
  
  
 {anchor:step1}
  
 h3. Part 1: Configure Web.xml For Spring Security
  
 The web.xml below contains additional parameters showing where the spring configuration is located, the Spring Security filter chain, the context loader listener, and the SessionEventPublisher. These should be added to any existing ICEfaces web.xml configuration parameters show below in step 3.
  
 {code:xml|title=web.xml}<?xml version="1.0" encoding="UTF-8"?>
 <web-app 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-app_2_5.xsd"
  version="2.5">
  <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
  /WEB-INF/applicationContext.xml
  /WEB-INF/applicationContext-security.xml
  </param-value>
  </context-param>
  <filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  
  <filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
  <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
  </listener> </web-app>
 {code}
 {anchor:step2}
  
h3. Part 2: Configure Your applicationContext.xml For Spring Security
  h3. Part 2: Configure Your security-config.xml For Spring Security
  
In this step we configure Spring Security in the file applicationContext-security.xml.
 {code:xml|title=applicationContext-security.xml}<?xml version="1.0" encoding="UTF-8"?>
  In this step we configure Spring Security in the file security-config.xml.
 {code:xml|title=security-config.xml}<?xml version="1.0" encoding="UTF-8"?>
  
 <beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-3.1.xsd">
  
<!-- key configuration here is an entry point to be used by security intercepts -->
  <http realm="Sample Realm" entry-point-ref="authenticationEntryPoint">
  <!-- Configure Spring Security -->
  <http auto-config="false"
  use-expressions="true"
  access-denied-page="/spring/login">
  
<!-- any role that is used to protect a directory, can be multiples -->
  <intercept-url pattern='/secure/**' access='ROLE_READER' />
   <form-login login-page="/spring/login"
  login-processing-url="/spring/loginProcess"
  default-target-url="/spring/main" always-use-default-target="true"
  authentication-failure-url="/spring/login?login_error=1" />
  
<!-- enable form login to use UsernamePasswordAuthenticationFilter [/j_spring_security_check] -->
  <form-login login-page="/general/logins/htmlLogin.faces"
  authentication-failure-url="/general/logins/loginFailed.faces"/>
   <!-- When using custom filters, please make sure the positions do not conflict with default filters.
  Alternatively you can disable the default filters by removing the corresponding child elements from
  http and avoiding the use of http auto-config='true'. -->
  
<!-- logout page uses the default LogoutFilter, no changes are needed as IT accepts a GET call... -->
  <!-- here is an example logout link:
  <a href="#{request.contextPath}/j_spring_security_logout">Logout</a> -->
  <logout logout-url="/j_spring_security_logout"
  logout-success-url="/general/main.faces"
  invalidate-session="true"/>
   <custom-filter ref="exceptionTranslationFilter" before="FILTER_SECURITY_INTERCEPTOR" />
  
  <!--<session-management invalid-session-url="/spring/sessionExpired.jsf"/>-->
  
  <logout logout-url="/spring/logout" logout-success-url="/spring/logoutSuccess"/>
  <intercept-url pattern="/secure" method="POST" access="hasRole('ROLE_SUPERVISOR')"/>
  </http>
  
<beans:bean id="authenticationEntryPoint"
  class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
  <beans:property name="loginFormUrl" value="/general/logins/htmlLogin.faces" />
  </beans:bean>
   <!--
  Define local authentication provider, a real app would use an external provider (JDBC, LDAP, CAS, etc)
  
<!-- test with this before you hook up your LDAP or other Authentication Manager -->
  <authentication-manager alias="authenticationManager">
   usernames/passwords are:
  keith/melbourne
  erwin/leuven
  jeremy/atlanta
  scott/rochester
  -->
  <authentication-manager>
  <authentication-provider>
<password-encoder hash="md5"/>
  <user-service>
<user name="joe.blow@icesoft.com" password="pass1234" authorities="ROLE_READER"/>
  <user name="ben.simpson@icesoft.com" password="pass5678" authorities="ROLE_READER"/>
   <user name="keith" password="417c7382b16c395bc25b5da1398cf076"
  authorities="ROLE_USER, ROLE_SUPERVISOR"/>
  <user name="erwin" password="12430911a8af075c6f41c6976af22b09"
  authorities="ROLE_USER, ROLE_SUPERVISOR"/>
  <user name="jeremy" password="57c6cbff0d421449be820763f03139eb" authorities="ROLE_USER"/>
  <user name="scott" password="942f2339bf50796de535a384f0d1af3e" authorities="ROLE_USER"/>
  </user-service>
  </authentication-provider>
  </authentication-manager>
  
 
  <beans:bean id="sessionManagementFilter"
  class="org.springframework.security.web.session.SessionManagementFilter">
  <beans:constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
  </beans:bean>
  
  
  <!-- http://static.springsource.org/spring-security/site/docs/3.1.x/reference/core-web-filters.html -->
  <beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
  <beans:property name="accessDeniedHandler" ref="jsfAccessDeniedHandler"/>
  <beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
  </beans:bean>
  
  <beans:bean id="jsfAccessDeniedHandler" class="com.icesoft.spring.security.JsfAccessDeniedHandler">
  <beans:property name="loginPath" value="/spring/login" />
  <beans:property name="contextRelative" value="true" />
  </beans:bean>
  
  <beans:bean id="authenticationEntryPoint" class="com.icesoft.spring.security.JsfLoginUrlAuthenticationEntryPoint">
  <beans:property name="loginFormUrl" value="/spring/login"/>
  <beans:property name="redirectStrategy" ref="jsfRedirectStrategy" />
  </beans:bean >
  
  
  <beans:bean id="jsfRedirectStrategy" class="com.icesoft.spring.security.JsfRedirectStrategy"/>
  <beans:bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
  
 </beans:beans>
 
 {code}
 {anchor:step3}
  
 h3. Part 3: Configure Web.xml For JSF
  
 In this step we extend the web.xml to support JSF like we would any other ICEfaces application.
 {code:xml|title=web.xml}...
  <servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet>
  <servlet-name>Resource Servlet</servlet-name>
  <servlet-class>com.icesoft.faces.webapp.CompatResourceServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>/icefaces/*</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
  <servlet-name>Resource Servlet</servlet-name>
  <url-pattern>/xmlhttp/*</url-pattern>
  </servlet-mapping>
 ...
 {code}
  
 h3. Step 4: Configure Your Spring Security redirectStrategy
  
 The example configuration below contains all of the previous security configurations and an added session management filter. When the session
 expires the user should be routed to a session expired page. The additional configuration provided is required to help redirect ajax based events like
 actionListeners attached to ice:commandButton tags.
  
 {code:xml|title=applicationContext-security.xml}<?xml version="1.0" encoding="UTF-8"?>
 <beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-3.0.xsd">
  
  <!-- key configuration here is an entry point to be used by security intercepts -->
  <http realm="Sample Realm" entry-point-ref="authenticationEntryPoint" auto-config="false">
  
  <custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" />
  <!-- any role that is used to protect a directory, can be multiples -->
  <intercept-url pattern='/secure/**' access='ROLE_READER' />
  
  <!-- enable form login to use UsernamePasswordAuthenticationFilter [/j_spring_security_check] -->
  <form-login login-page="/general/logins/htmlLogin.faces"
  authentication-failure-url="/general/logins/loginFailed.jsf"/>
  
  <!-- logout page uses the default LogoutFilter, no changes are needed as IT accepts a GET call... -->
  <!-- here is an example logout link:
  <a href="#{request.contextPath}/j_spring_security_logout">Logout</a> -->
  <logout logout-url="/j_spring_security_logout"
  logout-success-url="/general/main.jsf"
  invalidate-session="true"/>
  </http>
  
  <beans:bean id="authenticationEntryPoint"
  class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
  <beans:property name="loginFormUrl" value="/general/logins/login.jsf" />
  </beans:bean>
  
  <!-- test with this before you hook up your LDAP or other Authentication Manager -->
  <authentication-manager alias="authenticationManager">
  <authentication-provider>
  <user-service>
  <user name="joe.blow@icesoft.com" password="pass1234" authorities="ROLE_READER"/>
  <user name="ben.simpson@icesoft.com" password="pass5678" authorities="ROLE_READER"/>
  </user-service>
  </authentication-provider>
  </authentication-manager>
  
  <beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
  <beans:constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
  </beans:bean>
  
  <beans:bean id="jsfRedirectStrategy" class="com.icesoft.spring.security.JsfRedirectStrategy"/>
  <beans:bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
  
 </beans:beans>
 {code}
  
 h3. Resources
  
 For more information on Spring Security, please check out the content below:
 * [Spring Security Tutorials|http://static.springsource.org/spring-security/site/articles.html|Spring Security Tutorials]
 * [Spring Security Documentation|http://static.springsource.org/spring-security/site/docs/3.1.x/reference/core-web-filters.html|Spring Security Documentation]

© Copyright 2018 ICEsoft Technologies Canada Corp.