Announcement Announcement Module
Collapse
No announcement yet.
Integrating with SiteMinder Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Integrating with SiteMinder

    I have to integrate web app with SiteMinder. User authentication would be done on SiteMinder that would set SM_USER, SM_ROLE, SM_DEPARTMENT and few other values into HTTP Headers which are required in the web app.

    I have achieved this writing the following. Though this works fine, but due to lack of documentation I am not sure if this is the correct approach. Suggestions are welcome

    1. Added class MyWebAuthenticationDetailsSource extending WebAuthenticationDetailsSource setting clazz as MyPreAuthenticatedGrantedAuthoritiesWebAuthenticat ionDetails

    Code:
    public class MyWebAuthenticationDetailsSource extends
    		WebAuthenticationDetailsSource {
    
    	public MyWebAuthenticationDetailsSource() {
    		super
    				.setClazz(MyPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails.class);
    	}
    }
    2. Added MyPreAuthenticatedGrantedAuthoritiesWebAuthenticat ionDetails extending PreAuthenticatedGrantedAuthoritiesWebAuthenticatio nDetails as I would like to populate additional information from HTTP Headers (SM_DEPARTMENT etc) and also to get granted authorities from HTTP Header (SM_ROLE)

    Code:
    public class MyPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails
    		extends PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails {
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	private String authoritiesRequestHeader = "SM_ROLE";
    
    	private Map<String, String> additionalHeaders;
    
    	public MyPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(
    			HttpServletRequest request) {
    		super(request);
    		setPreAuthenticatedAuthorities();
    	}
    
    	@SuppressWarnings("unchecked")
    	public void doPopulateAdditionalInformation(HttpServletRequest request) {
    		additionalHeaders = new HashMap<String, String>();
    
    		Enumeration<String> allHeaders = request.getHeaderNames();
    		while (allHeaders.hasMoreElements()) {
    			String header = allHeaders.nextElement();
    			if (header.toUpperCase().startsWith("SM_")) {
    				additionalHeaders.put(header.toUpperCase(), request.getHeader(header));
    			}
    		}
    	}
    
    	private void setPreAuthenticatedAuthorities() {
    		String preAuthenticatedAuthorities = additionalHeaders
    				.get(authoritiesRequestHeader);
    
    		if (preAuthenticatedAuthorities == null) {
    			throw new PreAuthenticatedCredentialsNotFoundException(
    					authoritiesRequestHeader + " header not found in request.");
    		}
    
    		String[] tokens = StringUtils
    				.commaDelimitedListToStringArray(preAuthenticatedAuthorities);
    		List<String> authoritiesAsStrings = new ArrayList<String>();
    
    		for (int i = 0; i < tokens.length; i++) {
    			String currentToken = tokens[i].trim();
    			authoritiesAsStrings.add(currentToken);
    		}
    
    		UserAttribute userAttrib = new UserAttribute();
    		userAttrib.setAuthoritiesAsString(authoritiesAsStrings);
    
    		setGrantedAuthorities(userAttrib.getAuthorities());
    	}
    
    	public Map<String, String> getAdditionalHeaders() {
    		return additionalHeaders;
    	}
    }
    3. Added the following in applicationContext.xml. Added the new filter preAuthenticationProcessingFilter.

    Code:
    <bean id="preAuthenticationProcessingFilter"
    	class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    		<property name="authenticationManager" ref="authenticationManager" />
    		<property name="principalRequestHeader" value="SM_USER" />
    		<property name="authenticationDetailsSource" ref="myWebAuthenticationDetailsSource" />
    	</bean>
    
    	<bean id="myWebAuthenticationDetailsSource" class="com.test.common.MyWebAuthenticationDetailsSource" />
    
    	<bean id="authenticationManager"
    		class="org.springframework.security.authentication.ProviderManager">
    		<property name="providers">
    			<list>
    				<ref bean="preAuthenticationProvider" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="preAuthenticationProvider"
    		class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    		<property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService" />
    	</bean>
    
    	<bean id="preAuthenticatedUserDetailsService"
    		class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService" />
    4. Now principal, authorities, additional information can be accessed using
    Code:
    Authentication auth = SecurityContextHolder.getContext()
    				.getAuthentication();
    System.out.println("Principal " + auth.getName());
    System.out.println("Authorities " + auth.getAuthorities());
    
    MyPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails d = (MyPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails) auth
    				.getDetails();
    System.out.println("Additional Headers " + d.getAdditionalHeaders());

  • #2
    Looks good to me. You should be able to use WebAuthenticationDetailsSource itself, and simply set the Class using setter injection:

    Code:
    <bean id="myWebAuthenticationDetailsSource" class="org.springframework.security.web.authentication.WebAuthenticationDetailsSource">
      <property name="class" value="fully.qualified.name.of.MyPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails"/>
    </bean>

    Comment

    Working...
    X