Announcement Announcement Module
Collapse
No announcement yet.
Easy to have 2 different login forms? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Easy to have 2 different login forms?

    Where 1 login form is redirected to when a particular set of secure URLs are attempted to be opened by a non-logged in user and another login form is redirected to when a different set of secure URLs are attempted to be opened.

    The 2 login forms would have separate default URLs to go to once logged in as well. Is this easy to implement in Spring Security? I have the single login form mechanism working perfect now. I guess I could always implement this functionality by having my alternate secure URLs non-secure and just check for credentials manually, then redirect appropriately and do all the login/signup work manually for the alternate login form, but this is the type of plumbing I want Spring Security to handle...

  • #2
    You will need to use a custom AuthenticationProcessingFilterEntryPoint (to handle the redirect, depending on the URL), two login pages (with different form actions) and two separately configured AuthenticationProcessingFilters to handle the different form actions and perform the redirect to the appropriate target.

    Comment


    • #3
      Thanks for responding Luke. So looks like I simply subclass AuthenticationProcessingFilterEntryPoint overriding its determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) method. I return back a String of the form "/login" or "/login2" depending on which login form I want it to bring up after looking at the request.getServletPath(). I write my own logic to determine which login form to to return.

      Then I simply specify 2 different AuthenticationProcessingFilter beans to listen to 2 different urls the my 2 login forms submit to.

      Do I have all this right? How do I specify the AuthenticationProcessingFilter and EntryPoint in my xml configuration? This is how I currently have my login form specified:

      Code:
          <http auto-config='true'>
              <intercept-url pattern="/secure-urls" access="IS_AUTHENTICATED_REMEMBERED"/>
              <form-login login-page="/login-page" authentication-failure-url="/login-failure" default-target-url="/login-default" login-processing-url="/login-check"/>
              <logout logout-url="/logout" logout-success-url="/logout-success"/>
              <remember-me token-validity-seconds="31536000" data-source-ref="dataSource"/>
          </http>

      Comment


      • #4
        Hi, I'm also looking for a way to have multiple login forms with spring-security. I was thinking I could manually set the filter chain:

        HTML Code:
            <bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
        	<sec:filter-chain-map path-type="ant">
                	<sec:filter-chain pattern="/url1/*" filters="httpSessionContextIntegrationFilter,url1AuthenticationProcessingFilter,url1ExceptionTranslationFilter,filterSecurityInterceptor"/>
                	<!-- <sec:filter-chain pattern="/url2/*" filters="httpSessionContextIntegrationFilter,url2AuthenticationProcessingFilter,url2exceptionTranslationFilter,filterSecurityInterceptor"/> -->
                	<!-- <sec:filter-chain pattern="/url3/*" filters="httpSessionContextIntegrationFilter,url3AuthenticationProcessingFilter,url3exceptionTranslationFilter,filterSecurityInterceptor"/> -->
            	</sec:filter-chain-map>
            </bean>
        
            <bean id="dataSource"
        		class="org.springframework.jndi.JndiObjectFactoryBean"
        		p:jndiName="jdbc/datasource-ds"
        		p:resourceRef="true" />
        
            <bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />
         
            <bean id="userService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
            	<property name="dataSource" ref="dataSource" />
                <property name="enableGroups" value="true" />
            </bean>
        
            <bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
        		<property name="userDetailsService" ref ="userService"/>
            </bean>
        
            <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
        		<property name="providers">
        			<list>
        				<ref local="daoAuthenticationProvider"/>
        			</list>
        		</property>
            </bean>
        
            <bean id="url1AuthenticationProcessingFilter" 
        		class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter" 
        		p:authenticationManager-ref="authenticationManager">
        			<property name="filterProcessesUrl" value="/j_spring_security_check" />
        			<property name="authenticationFailureUrl" value="/doLogin.htm?login_error=1"/>
        			<property name="defaultTargetUrl" value="/index.htm" />
        	</bean>
        
           <bean id="url1LoginAuthenticationEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
        		<property name="loginFormUrl" value="/doLogin.htm" />
        	</bean>
        
           <bean id="url1ExceptionTranslationFilter" 
        		class="org.springframework.security.ui.ExceptionTranslationFilter" 
        		p:authenticationEntryPoint-ref="url1LoginAuthenticationEntryPoint" />
        
           <bean id="roleVoter" class="org.springframework.security.vote.RoleVoter">
        		<property name="rolePrefix" value="ROLE_" />
           </bean>
        	
           <bean id="accessDecisionManager" class="org.springframework.security.vote.UnanimousBased">
        		<property name="decisionVoters">
        			<list>
        				<ref bean="roleVoter" />
        			</list>
        		</property>
           </bean>
        	
           <bean id="filterSecurityInterceptor" 
        		class="org.springframework.security.intercept.web.FilterSecurityInterceptor"
        		p:authenticationManager-ref="authenticationManager"
        		p:accessDecisionManager-ref="accessDecisionManager">
        
        		<property name="objectDefinitionSource">
            		<sec:filter-invocation-definition-source>
              			<sec:intercept-url pattern="/url1/*" access="ROLE_1" />
                    		<sec:intercept-url pattern="/url2/*" access="ROLE_2" />
                    		<sec:intercept-url pattern="/url3/*" access="ROLE_3" />    
            		</sec:filter-invocation-definition-source>                
          		</property>
        	</bean>
        When I try to access a restricted URL, I'm redirected to the login screen, which is fine.
        The problem comes when I do "POST" and j_spring_security_check is invoked. Then, I get a 404 not found error.

        I would like to know what's wrong here, as I'm not an expert in Spring security.

        Comment


        • #5
          Originally posted by mueller View Post
          Do I have all this right? How do I specify the AuthenticationProcessingFilter and EntryPoint in my xml configuration? This is how I currently have my login form specified:

          Code:
              <http auto-config='true'>
                  <intercept-url pattern="/secure-urls" access="IS_AUTHENTICATED_REMEMBERED"/>
                  <form-login login-page="/login-page" authentication-failure-url="/login-failure" default-target-url="/login-default" login-processing-url="/login-check"/>
                  <logout logout-url="/logout" logout-success-url="/logout-success"/>
                  <remember-me token-validity-seconds="31536000" data-source-ref="dataSource"/>
              </http>
          You need to remove the form-login element (which creates an AuthenticationProcessingFilter) and declare the custom filters as explicit beans, adding them into the chain as described in the namespace chapter of the manual. It also explains how to use a custom entry point. You can use the namespace appendix as a supplementary reference for how the elements and attributes are implemented.

          Remove the "auto-config" attribute too.

          Comment


          • #6
            Were you able to get this working? It seems like something the framework should allow - determining which login form applies to which page, possibly within the intercept-url mappings.

            Comment


            • #7
              I haven't had an hour free to follow Luke's suggestions and get it all to work, so I'm just using a workaround for now. But I completely agree this should be basic included functionality with Spring Security that is configurable with 1 line of XML. I have to imagine this is a very common need of any modern web application of reasonable complexity.

              Comment


              • #8
                The problem is that security requirements are wide and varied and if you want them all to be configurable in "one line of XML" then your namespace rapidly becomes cluttered and unmanageable. The whole point of it is to provide a simple starting point without having to understand the underlying architecture. Therefore a primary driver is to keep it simple.

                There comes a point when the best place for customization is in Java code which extends the framework classes or supplies implementations of strategies that are used.

                Comment


                • #9
                  Just my opinion of course, but I disagree with the namespace becoming cluttered and unmanageable with basic functionality. There are XML confurations which cover dramatically more capabilities (non-security related I'm talking about) and aren't cluttered. Seems to me that Spring Security isn't very simple to learn and use if your requirements are anything but the most basic web forms. At that point you basically have to write your own code and deal with the mess of dependencies in the underlying architecture that you'll be reading about for a while. Isn't that what a library is supposed to abstract away? I'm certainly no expert in security of any form and the prospect of depending on my own code for security is a little annoying, to say the least.

                  Maybe I just need to take the time and read the complete documentation... But Spring Security could certainly be made more intuitive.

                  Comment


                  • #10
                    Having two separate login forms and processing URLs within the same application isn't actually a very common requirement. Multiple variations of a login page (e.g. for branding purposes) are also easlily handled using a single URL which is mapped to a controller, allowing the controller to decide how to render the page. This makes more sense than using a basic JSP and is a much cleaner approach. Adding an option to specify a different login page for each configured URL would not therefore serve any useful purpose.

                    Comment


                    • #11
                      Where is an example of using a LoginController to serve muliple login pages? I agree that I seem to fight with Spring Security more than I should.

                      Comment

                      Working...
                      X