Google

Oct 11, 2013

Spring security - Part3

This is a continuation of Spring security part1 and part2.
This part covers some handy tips.

Q. How will you access Spring security context details within a method that is annotated with @RolesAllowed?
A. The answer is to use the SecurityContextHolder class's static method. It is a ThreadLocal class. Each thread has its own value of ThreadLocal  pointing to the same instance of SecurityContextHolder  class. Here is the sample code snippet. You can get the principal and the authorities as shown below.


 
 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
 Collection authorities = authentication.getAuthorities();
 Object principal = authentication.getPrincipal();
 
Q. How do you map multiple authentication managers?
A. You can define multiple authentiaction managers based on URL patterns as shown below.

<?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:security="http://www.springframework.org/schema/security"
 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.1.xsd
                      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http auto-config="false" pattern="/app1/reporting/**" authentication-manager-ref="app1ReportingAuthenticationManager" entry-point-ref="app1ReportingProcessingFilterEntryPoint">
        <security:custom-filter position="PRE_AUTH_FILTER"
                                ref="app1ReportingSiteminderFilter" />
        <logout logout-url="/j_spring_security_logout"
                logout-success-url="" invalidate-session="true" />
    </http>

 <http auto-config="false" pattern="/app1/calculating/**" authentication-manager-ref="app1CalculatingAuthenticationManager" entry-point-ref="app1Calculating">
  <security:custom-filter position="PRE_AUTH_FILTER"
   ref="app1CalculatingSiteminderFilter" />
     <logout logout-url="/j_spring_security_logout"
   logout-success-url="" invalidate-session="true" />
 </http>

 <http auto-config="false" pattern="/app2/validating/**" entry-point-ref="app2ValidatingProcessingFilterEntryPoint"
 entry-point-ref="app2Validating">
  <security:custom-filter position="PRE_AUTH_FILTER"
   ref="app2ValidatingSiteminderFilter" />
  <intercept-url pattern="/app2/**/details.csv*"
   access="ROLE_viewer, ROLE_standard, ROLE_senior" />
  <logout logout-url="/j_spring_security_logout"
   logout-success-url="" invalidate-session="true" />
 </http>

</beans:beans>


Here is a sample config for one of the http mappings:

<?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:security="http://www.springframework.org/schema/security"
 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.1.xsd
                      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

 <beans:bean id="app1ReportingProcessingFilterEntryPoint"
  class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />

 <beans:bean id="app1ReportingSiteminderFilter"
  class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
  <beans:property name="principalRequestHeader" value="SM_USER" />
  <beans:property name="authenticationManager" ref="app1ReportingAuthenticationManager" />
  <beans:property name="exceptionIfHeaderMissing" value="false" />
 </beans:bean>

 <security:authentication-manager id="app1ReportingAuthenticationManager">
  <security:authentication-provider
   ref="app1ReportingAuthProvider" />
 </security:authentication-manager>

 <beans:bean id="app1ReportingAuthProvider"
  class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
  <beans:property name="preAuthenticatedUserDetailsService">
   <beans:bean id="myAppUserDetailsServiceWrapper"
    class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
    <beans:property name="userDetailsService" ref="myUserDetailsService" />
   </beans:bean>
  </beans:property>
 </beans:bean>

 <beans:bean id="myUserDetailsService"
  class="com.myapp.MyUserDetailsServiceImpl">
  <beans:property name="domain" value="FUNDS" />
 </beans:bean>

</beans:beans>


Q. The roles are stored in the session, how will you make sure that the roles are read every time from the database?
A. It is generally a good practice to leave the roles in the session, and the session gets invalidated on logout. There are times you want the roles to be read from the database and not from the session. This can be accomplished by

Step 1: Writing a response filter to remove the roles from the Http Session. Here is the code snippet.

 
   HttpSession session = request.getSession();
   session.removeAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);

The SecurityHolder.getContext( ) has a clearContents method, but it will only remove it from  the current thread but not the session. 

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home