Announcement Announcement Module
Collapse
No announcement yet.
Help needed again - Spring 3.0.x security + SiteMinder Integration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help needed again - Spring 3.0.x security + SiteMinder Integration

    I am using Spring Security 3.0. What I want to implement is that the user should be shown a login page (part of our webapp) where he enter his username and password. On clicking submit the request will travel to Siteminder web agent to be authenticated. On succesful authentication the username appended would be added in the header with key 'SM_USER'. Once request comes back to our webapp we let Spring take care of authorization. So in short, want to implement Authentication by Siteminder and Authorization by Spring Security.

    My web.xml is as follows:

    <!-- Security Configuration -->
    <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFil terProxy</filter-class>
    </filter>

    <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>


    My security-config.xml is as follows.

    <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/schem...-beans-3.0.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <http auto-config='true'>
    <intercept-url pattern="/index.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/WEB-INF/login/login.jsp*" filters="none" />
    <intercept-url pattern="/flex/tsm/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/**" access="ROLE_DEALER" />
    <form-login login-page='/WEB-INF/login/login.jsp' default-target-url='/spring/home'
    always-use-default-target="false" />

    <http-basic />
    <session-management invalid-session-url="/spring/home" />
    <logout logout-success-url="/logout.jsp" invalidate-session="true" />
    <custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
    </http>

    <!-- Siteminder configuration Begin-->
    <beans:bean id="siteminderFilter"
    class="org.springframework.security.web.authentica tion.preauth.RequestHeaderAuthenticationFilter">
    <beans: property name="principalRequestHeader" value="SM_USER" />
    <beans: property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

    <authentication-manager alias="authenticationManager">
    <authentication-provider ref="gtwPreAuthenticationProvider"/>
    </authentication-manager>

    <beans:bean id="gtwPreAuthenticationProvider"
    class="org.springframework.security.web.authentica tion.preauth.PreAuthenticatedAuthenticationProvide r">
    <beans: property name="preAuthenticatedUserDetailsService">
    <beans:bean id="userDetailsServiceWrapper"
    class="org.springframework.security.core.userdetai ls.UserDetailsByNameServiceWrapper">
    <beans: property name="userDetailsService" ref="userDetailsService" />
    </beans:bean>
    </beans: property>
    </beans:bean>

    <beans:bean id="userDetailsService"
    class="com.MY.gtw.common.authentication.gtwUserDet ailsService" />
    <!-- Siteminder configuration End -->

    </beans:beans>

    When I try to access the login.jsp using URL - http://localhost:8080/gtw/login/login.jsp , I get the following exception:

    Mar 9, 2011 9:31:13 AM org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet jsp threw exception
    org.springframework.security.web.authentication.pr eauth.PreAuthenticatedCredentialsNotFoundException : SM_USER header not found in request.
    at org.springframework.security.web.authentication.pr eauth.RequestHeaderAuthenticationFilter.getPreAuth enticatedPrincipal(RequestHeaderAuthenticationFilt er.java:43)
    at org.springframework.security.web.authentication.pr eauth.AbstractPreAuthenticatedProcessingFilter.doA uthenticate(AbstractPreAuthenticatedProcessingFilt er.java:98)
    at org.springframework.security.web.authentication.pr eauth.AbstractPreAuthenticatedProcessingFilter.doF ilter(AbstractPreAuthenticatedProcessingFilter.jav a:86)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.authentication.lo gout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.context.SecurityC ontextPersistenceFilter.doFilter(SecurityContextPe rsistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.web.filter.RequestContextFilte r.doFilterInternal(RequestContextFilter.java:83)
    at org.springframework.web.filter.OncePerRequestFilte r.doFilter(OncePerRequestFilter.java:76)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.FilterChainProxy. doFilter(FilterChainProxy.java:149)
    at org.springframework.web.filter.DelegatingFilterPro xy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterPro xy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.servic e(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11Conn ectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run( JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:595)



    I am using the following jars:

    spring-security-config-3.0.3.RELEASE.jar
    spring-security-core-3.0.3.RELEASE.jar
    spring-security-web-3.0.3.RELEASE


    Am I missing some jars or some configuration tags in security-config.xml or web.xml?

    Please help me urgently ...

    Thanks in advance ...
    Last edited by kelkarp; Mar 9th, 2011, 11:33 AM.

  • #2
    You need to set RequestHeaderAuthenticationFilter.exceptionIfHeade rMissing to false if you do not want to error out when the header is missing. Alternatively you can override the getPreAuthenticatedPrincipal method to provide logic to conditionally error out when the header is missing. One more option is to just not apply RequestHeaderAuthenticationFilter to urls you do not want filtered.

    Comment


    • #3
      Thanks rwinch!

      It seems to be working with:
      <property name="exceptionIfHeaderMissing" value="false" />

      Comment


      • #4
        PreAuthenticatedCredentialsNotFoundException: SM_USER header not found in request

        Hello,

        I seem to be facing the exact same problem. I am however reluctant to use
        Code:
        <property name="exceptionIfHeaderMissing" value="false" />
        My configuration is as below for the application
        web.xml
        Code:
        <!-- 2. Defining Spring Configuration files -->
        	<listener>
        		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        	</listener>
        	<context-param>
        		<param-name>contextConfigLocation</param-name>
        		<param-value>
           			/WEB-INF/config/applicationContext.xml  
           			/WEB-INF/config/applicationContext-security.xml 		 	
           		 </param-value>
        	</context-param>
        
        <!-- 3. Defining Spring Security filter -->
        	<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>
        
        <!-- 4. Defining Struts2 Configuration -->
        	<filter>
        		<filter-name>struts2</filter-name>
        		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        	</filter>
        	<filter-mapping>
        		<filter-name>struts2</filter-name>
        		<url-pattern>/*</url-pattern>
        	</filter-mapping>

        applicationContext-security.xml
        Code:
        <http auto-config='true'>    	
            	
            	<!-- URL Pattern's for which Spring Security should not be applied -->
            	<intercept-url pattern="/css/**" filters="none" />
            	<intercept-url pattern="/images/**" filters="none" />
            	<intercept-url pattern="/js/**" filters="none" />
                <intercept-url pattern="/struts/**" filters="none" />
            	<intercept-url pattern="/index.action*" filters="none" />
            	<intercept-url pattern="/logoutSiteminder.action" filters="none" />
            	
            	<!-- Defining role based access for different URL Pattern's -->
            	<intercept-url pattern="/*.action*" access="ROLE_USER" />
               
                <!-- Logout URL -->
            	<logout logout-success-url="/logoutSiteminder.action" />
            	   
            	<!-- Adding SiteMinder Authentication Filter with Spring Security keyword PRE_AUTH_FILTER  -->   
            	<custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
                     	
        </http>
        
        
                <!-- Defining SiteMinder Authentication Filter (SM_USER is fetched from request header) -->
        	<beans:bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
                  <beans:property name="principalRequestHeader" value="SM_USER"/>
                  <beans:property name="authenticationManager" ref="authenticationManager" />  
        	</beans:bean>
        
        	<!-- Defining Custom Authentication Provider as a preauthAuthProvider -->
        	<beans:bean id="preauthAuthProvider"
              class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
           		<beans:property name="preAuthenticatedUserDetailsService">
        			<beans:bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
        				<beans:property name="userDetailsService" ref="userDetailsService"/>
        			</beans:bean>   
           		</beans:property>
        	</beans:bean>
        
        	<!-- Providing preauthAuthProvider  to Authentication Manager -->
        	<authentication-manager alias="authenticationManager" >
            	      <authentication-provider ref="preauthAuthProvider"/>
        	</authentication-manager>

        I figured this might be related to
        https://jira.springsource.org/browse/SEC-1249
        So adding its reference over here.

        Everything works fine for me.
        • Login screen is displayed.
        • Successfull Siteminder Authentication + Spring Authorization is done
        • Home page is displayed
        • However wherever i have reference for js file like the one below
          Code:
          /ContextRoot/struts/js/jquery.struts2.js
          /ContextRoot/struts/js/jquery.subscribe.js
          I am getting the error
          Code:
          org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: SM_USER header not found in request.

        I do not understand why am i getting this error in the first place only for the javascript files at a particular path as mentioned above ?
        And why was this not an issue in Spring Security 2.0.5. ?


        Please note that i face this issue with or without the below line in my applicationContext-security.xml.
        Code:
        <intercept-url pattern="/struts/**" filters="none" />
        And with and without "an unprotected resource filter /ContextRoot/struts/* to Siteminder"

        Help to resolve this would be greatly appreciated.
        This is quite on priority for me.


        Regards,
        Darshan Shroff
        [email protected]
        http://www.linkedin.com/in/darshanshroff
        Last edited by darshan.shroff; Apr 10th, 2011, 11:45 PM. Reason: Added related jira SEC-1249

        Comment


        • #5
          Darshan,

          The SiteMinder WebAgent monitors URLs in resource requests, and enforces the security policies for these resources. The WebAgent can be configured to ignore certain file extensions and perform an auto-authorize. SiteMinder ignores security by default for certain file types including gifs, jpegs, etc. Additional file types can be auto-authorized by specifying the file extension in the ignoreextensions attribute in WebAgent.conf.

          For example, if your application does not need security on PDF files, the web site administrator can add “pdf” to the WebAgent.conf:
          ignoreext=".ccc, .class, .fcc, .gif, .jpeg, .jpg, .ntc, .png, .scc, .sfcc, .pdf”

          Note: URLs do not always have periods, which is common with Servlets, for example, /mydir/servlets. An unauthorized user can append a bogus resource to the end of the URL when making a request, such as, /mydir/servlets/file.gif. Because this resource has an extension that the Web Agent is configured to ignore, the unauthorized user gains access to /mydir/servlets. Be sure to protect all such resources on the Application Server by implementing checks in your servlet code

          Comment


          • #6
            Kelkarp,

            I do know that by making configuration changes at Siteminder level, one can unprotect certain resources/urls. I have already made such changes for my application. I however want to know the reason why i am facing below issue in Spring Security 3.0.5.
            Last edited by darshan.shroff; Mar 28th, 2011, 11:44 PM.

            Comment


            • #7
              Originally posted by darshan.shroff View Post
              Please note that i face this issue with or without the below line in my applicationContext-security.xml.
              I assume you have only added the springSecurityFilterChain to your web.xml and the the RequestHeaderAuthenticationFilter is only specified in your spring configuration. If you specify filters=none for a path that matches your js then it will not invoke the RequestHeaderAuthenticationFilter at all. Try turning up logging and see if that helps.

              Originally posted by darshan.shroff View Post
              Secondly can the exceptionIfHeaderMissing be applied to specific files only.
              Like for instance i only want to apply it to the pattern="/struts/js/**", can that be done ?
              If yes, can you please provide a sample custom filter.
              You would need to extend the RequestHeaderAuthenticationFilter and override the getPreAuthenticatedPrincipal method.

              Comment


              • #8
                Rwinch,

                You are correct with the your assumptions. I however do not understand why is it checking for the UID for a pattern which i have explicitly mentioned as filters=none.
                Logging is somewhat troublesome for us, since this is on the Testing environment, where the logs are controlled by the Application Server.

                You can check my detailed configuration here :-
                http://forum.springsource.org/showth...d=1#post351259

                Comment


                • #9
                  I don't see anything immediately wrong with your configuration, but often times when configurations get simplified the problem is hidden. There is the possibility I am overlooking something and someone else will be able to figure it out. Unfortunately, I don't think I will be able to help unless you can provide the logs for Spring Security durring a request to the js or preferably provide a simplified and complete example that you can post that reproduces your problem.

                  Comment

                  Working...
                  X