Announcement Announcement Module
Collapse
No announcement yet.
Multiple authentication mechanism for single application Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multiple authentication mechanism for single application

    Hi everybody,

    I just started with spring security for a new project that can be accessed in three different ways :
    • 1 B2C access
    • 2 B2B access

    Each access have its own authentication mechanism, for the B2C access it's a form-based login, and for the 2 B2B access, the login informations are retrieved from the URL.
    I'm looking for a clean enough way to achieve this, and thus got some questions :

    1/ Implement a simple Controller which dispatches to the right authentication mechanism (form or params in URL). In this cas, how to handle a specific logout and expired session ?

    2/ Setup 3 different configs, each having its own FilterChainProxy, and then 3 config file, not sure it is possible

    3/ Create 3 different applications, but not really what I want to do...

    Thanks for your replies

    Nabil

  • #2
    I think you should be able to do this using one filterChainProxy that has multiple processing filters. Different processing filters can handle different types of authentication. Each of these filters reference the same authenticationManager which in turn references an authenticationProvider for each type of authentication.

    You'd have to read up on this some more in the documentation. I'm still trying to get used to the details myself. I'm pretty sure what you're looking for can be done though, because I have an application that uses multiple authentication mechanisms.
    Last edited by Bron; Jun 11th, 2009, 01:03 PM. Reason: clarification

    Comment


    • #3
      Thank you for the reply, that's exactly what I wanted to do. I'm still looking for a good way to handle logging out (I think I should write my own LogoutFilter) and Session expire...

      Thanks again, that helped a lot

      Comment


      • #4
        Session expiration

        Session expiration should happen automatically. You can configure the session timeout in minutes in web.xml like so:

        Code:
          <session-config>
            <session-timeout>30</session-timeout>
          </session-config>

        Comment


        • #5
          Well, thank you for the reply, but when I talked about session expiration handling, I was thinking about something more like : "how to handle redirection depending on the authentication mechanism when a session expires ?".
          If the session expires, I don't know if that was a user logged as B2C way or one of the two B2B ways, because the SecurityContext is lost, and then don't know which page to forward to...

          I was thinking about using classical bean definition for the filterChainProxy, and then specify different patterns for each type of authentication, something like :

          Code:
          <bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
            <sec:filter-chain-map path-type="ant">
               <sec:filter-chain pattern="/B2C/**" filters="httpSessionContextIntegrationFilter,b2CProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
               <sec:filter-chain pattern="/B2BOne/**" filters="httpSessionContextIntegrationFilter,b2BOneProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
               <sec:filter-chain pattern="/B2BTwo/**" filters="httpSessionContextIntegrationFilter,b2BTwoProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
            </sec:filter-chain-map>
          </bean>
          But after doing this, can we still use http element and intercept-url, etc... ?

          Comment


          • #6
            Using different paths for different authentication types smells fishy to me, but I'm not sure if there is a much better idea. Are the pages all unique to a single type of authentication? For example, given pages PageA and PageB, which scenarios is most correct?
            1. PageA will only be used by B2C, and PageB will only be used by B2B.
            2. PageA and PageB will be used by both B2C and B2B.

            Comment


            • #7
              I agree with you, don't know if it's the best way to use different paths for different authentication mechanism, but it's the only way I found to handle session expiration depending on who was connected.

              To answer your question, unfortunatly PageA and PageB can be used by both B2C and B2B... So I'll have to duplicate my pages if I do it this way (not very clean...).

              If you have some other ideas, just let me know !

              Comment


              • #8
                You don't have to duplicate the pages, just the servlet mappings. You can map to URL's to the same controller.

                Comment


                • #9
                  Yep you're right...

                  Do you know if there is any other solution to handle session expiration ?

                  Comment


                  • #10
                    But after doing this, can we still use http element and intercept-url, etc... ?
                    I wondered this exact same thing. I was considering going through the feature request process and try and request this feature, but I doubt it will go through. Spring security is a minor re-factoring of acegi, with some syntax sugar provided by the namespace to make it easy for people to put together a web-page only application (no web services).

                    I looked to see if spring WS had solved this same problem because they have some kind of integration with the spring security; I didn't find a whole lot, I did not see it messing with the http filters, I think it might have pulled the password from the user details for message level security or something (i was kind of in a rush).

                    Unfortunately, the way the spring security namespace is currently implemented you cannot have more than 1 http element. The primary problem is that the http element does not correspond to a single object, and does not have an ID -- instead, the http element is a "macro" that expands to allot of interrelated configuration elements. For example the <url-intercept> tag gets mapped to at least two different filters (ChannelProcessingFilter to handle the "require SSL" concept, and FilterSecurityInterceptor to handle )

                    Having 3 http elements would require 3 ChannelProcessingFilter and 3 FilterSecurityInterceptors. In some cases you might want the different filters to act together, and other times seperated by some piece of context info (like the URL).

                    I expanded the security name space, you can see what is there:
                    Code:
                    <security:http auto-config="true">
                    	    <security:intercept-url pattern='/login.htm*' filters='none'/>  
                    	    <security:intercept-url pattern='/**' access='ROLE_USER' />
                    	    <security:form-login login-page='/login.htm' default-target-url='/home.htm' always-use-default-target='true' />
                    	  </security:http>
                    	
                        <security:authentication-provider>
                            <security:user-service>
                                <security:user name="rod" password="koala" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
                    	    </security:user-service>
                    	</security:authentication-provider>
                    Exapnds to this monster:
                    Code:
                    <bean name="_authenticationManager" class=org.springframework.security.config.NamespaceAuthenticationManager">
                      <property name="providerBeanNames" ref="[_anonymousAuthenticationProvider, _rememberMeAuthenticationProvider, org.springframework.security.providers.dao.DaoAuthenticationProvider#0]" />
                    
                    <bean name="_filterChainProxy" class=org.springframework.security.util.FilterChainProxy">
                      <property name="matcher" ref="org.springframework.security.util.AntUrlPathMatcher[requiresLowerCase='true']" />
                      <property name="stripQueryStringFromUrls" value="true" />
                      <property name="filterChainMap" ref="{/login.htm*=[]}" />
                    
                    <bean name="_httpSessionContextIntegrationFilter" class=org.springframework.security.context.HttpSessionContextIntegrationFilter">
                      <property name="allowSessionCreation" value="true" />
                      <property name="forceEagerSessionCreation" value="false" />
                    
                    <bean name="_filterChainProxyPostProcessor" class=org.springframework.security.config.FilterChainProxyPostProcessor">
                    
                    <bean name="_filterChainList" class=org.springframework.security.config.ConfigUtils$FilterChainList">
                      <property name="filters" ref="[<_httpSessionContextIntegrationFilter>, <_securityContextHolderAwareRequestFilter>, <_exceptionTranslationFilter>, <_filterSecurityInterceptor>, <_sessionFixationProtectionFilter>, <_anonymousProcessingFilter>, <_rememberMeFilter>, <_logoutFilter>, <_basicAuthenticationFilter>, <_formLoginFilter>]" />
                    
                    <bean name="_securityContextHolderAwareRequestFilter" class=org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter">
                    
                    <bean name="_accessManager" class=org.springframework.security.vote.AffirmativeBased">
                      <property name="decisionVoters" ref="[Root bean: class [org.springframework.security.vote.RoleVoter]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, Root bean: class [org.springframework.security.vote.AuthenticatedVoter]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]" />
                    
                    <bean name="_portMapper" class=org.springframework.security.util.PortMapperImpl">
                    
                    <bean name="_exceptionTranslationFilter" class=org.springframework.security.ui.ExceptionTranslationFilter">
                      <property name="createSessionAllowed" value="true" />
                    
                    <bean name="_filterSecurityInterceptor" class=org.springframework.security.intercept.web.FilterSecurityInterceptor">
                      <property name="accessDecisionManager" ref="<_accessManager>" />
                      <property name="authenticationManager" ref="<_authenticationManager>" />
                      <property name="objectDefinitionSource" ref="org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource@e6f7d2" />
                    
                    <bean name="_sessionFixationProtectionFilter" class=org.springframework.security.ui.SessionFixationProtectionFilter">
                      <property name="migrateSessionAttributes" value="true" />
                    
                    <bean name="_anonymousAuthenticationProvider" class=org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
                      <property name="key" value="doesNotMatter" />
                    
                    <bean name="_anonymousProcessingFilter" class=org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
                      <property name="userAttribute" value="roleAnonymous,ROLE_ANONYMOUS" />
                      <property name="key" value="doesNotMatter" />
                    
                    <bean name="_rememberMeServices" class=org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
                      <property name="key" value="SpringSecured" />
                    
                    <bean name="_rememberMeAuthenticationProvider" class=org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
                      <property name="key" value="SpringSecured" />
                    
                    <bean name="_rememberMeFilter" class=org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
                      <property name="authenticationManager" ref="<_authenticationManager>" />
                      <property name="rememberMeServices" ref="<_rememberMeServices>" />
                    
                    <bean name="_rememberMeServicesInjectionBeanPostProcessor" class=org.springframework.security.config.RememberMeServicesInjectionBeanPostProcessor">
                    
                    <bean name="_logoutFilter" class=org.springframework.security.ui.logout.LogoutFilter">
                      <property name="filterProcessesUrl" value="/j_spring_security_logout" />
                    
                    <bean name="_basicAuthenticationEntryPoint" class=org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
                      <property name="realmName" value="Spring Security Application" />
                    
                    <bean name="_basicAuthenticationFilter" class=org.springframework.security.ui.basicauth.BasicProcessingFilter">
                      <property name="authenticationManager" ref="<_authenticationManager>" />
                      <property name="authenticationEntryPoint" ref="<_basicAuthenticationEntryPoint>" />
                    
                    <bean name="_formLoginFilter" class=org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
                      <property name="alwaysUseDefaultTargetUrl" value="true" />
                      <property name="filterProcessesUrl" value="/j_spring_security_check" />
                      <property name="defaultTargetUrl" value="/home.htm" />
                      <property name="authenticationFailureUrl" value="/login.htm" />
                      <property name="authenticationManager" ref="<_authenticationManager>" />
                      <property name="invalidateSessionOnSuccessfulAuthentication" value="true" />
                      <property name="migrateInvalidatedSessionAttributes" value="true" />
                      <property name="rememberMeServices" ref="<_rememberMeServices>" />
                      <property name="allowSessionCreation" value="true" />
                    
                    <bean name="_formLoginEntryPoint" class=org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                      <property name="loginFormUrl" value="/login.htm" />
                    
                    <bean name="_entryPointInjectionBeanPostProcessor" class=org.springframework.security.config.EntryPointInjectionBeanPostProcessor">
                    
                    <bean name="_userServiceInjectionPostProcessor" class=org.springframework.security.config.UserDetailsServiceInjectionBeanPostProcessor">
                    
                    <bean name="org.springframework.security.providers.dao.DaoAuthenticationProvider#0" class=org.springframework.security.providers.dao.DaoAuthenticationProvider">
                      <property name="userDetailsService" ref="<_userDetailsService>" />
                    
                    <bean name="_userDetailsService" class=org.springframework.security.userdetails.memory.InMemoryDaoImpl">
                      <property name="userMap" ref="org.springframework.security.userdetails.memory.UserMap@19836ed" />
                    
                    <bean name="org.springframework.security.config.AuthenticationProviderBeanDefinitionParser$AuthenticationProviderCacheResolver#0" class=org.springframework.security.config.AuthenticationProviderBeanDefinitionParser$AuthenticationProviderCacheResolver">

                    Comment

                    Working...
                    X