Announcement Announcement Module
Collapse
No announcement yet.
Custom Authentication Manager with Spring Security 3.0.3 Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Custom Authentication Manager with Spring Security 3.0.3

    Hi everybody,

    Here is my problem : I'm building a custom login form, with a username, a password and some others fields. When I submit the form, the login/password is successfully checked withe te following code:
    Code:
        <global-method-security secured-annotations="enabled"  />
        
    	<http use-expressions="true">
        	<intercept-url pattern="/login/login.htm*" filters="none" />
            <intercept-url pattern="/secure/extreme/**" access="hasRole('ROLE_SUPERVISOR')"/>
            <intercept-url pattern="/transport/**" access="isAuthenticated()" />
            <intercept-url pattern="/**" access="permitAll" />
            <intercept-url pattern="/images" access="permitAll" />
            <intercept-url pattern="/css" access="permitAll" />
            <form-login login-page="/front/login.htm" default-target-url="/index.htm" />
            <logout logout-success-url="/index.htm" />
            <remember-me />
            <!-- Uncomment to limit the number of sessions a user can have -->
            <session-management>
                <concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
            </session-management>
        </http>
    
        <beans:bean id="userService" class="com.alea.server.services.UserService" />
        
        <authentication-manager>
            <authentication-provider user-service-ref="userService">
                <password-encoder hash="md5"/>      
            </authentication-provider>
        </authentication-manager>
    But there is no trace of my custom fields. So I decided (as I saw it was the right way) to overwrite the authentication manager, so I can set the custom parameters in a session and use them later in a Spring Controller. But I cannot find any working examples ....

    Is there an easiest way? Where can I find a working example?

    Thanks in advance

    Romain.

  • #2
    You can't override the namespace AuthenticationManager, and it has no access to the HttpSession in any case.

    You need to handle the extra parameters in the web tier. If you want to use them for authentication, then check the FAQ, as there is an entry on using extra authentication fields.

    Comment


    • #3
      what do you exactly mean by "the web tier" ?

      I do not need those informations for the authentication, just to catch them and save them somewhere they can be read by Spring (for i18n in my case).

      The problem I am confronted is that the extra informations are included in the login form (the /j_spring_security_check call as post parameters ). If the authentication is successfull, the user is then redirected by spring security to the page he asked, that is in facts, a Spring Controller.

      I don't know how to get the Spring Security form values in my Spring Controller, after the validation ...

      Comment


      • #4
        Why not just create a custom filter and access the request parameters from there? You could pull the request parameters into the session so that they would live through the redirect.

        Comment


        • #5
          I tried to implement this one : http://tejakantamneni.wordpress.com/...essing-filter/

          But it seems that the version is not correct : when I compile and run, I get a 503 error : no context loaded without any other information ...

          Edit: I just found 2.3.5 chapter in the doc. I'm trying to make that work, but an example should be very helpful ... what interface have I to implement? Wich classes have I to extend? How does I get my parameters in the filter?
          Last edited by romain.vdk; Jul 19th, 2010, 06:41 AM.

          Comment


          • #6
            Ok, I tried to create a filter like this, but the webapp doesn't launch

            Here is my config XML:
            Code:
            <?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: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.0.xsd
                                    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
            
                <global-method-security secured-annotations="enabled"  />
                
                <beans:bean id="languageFilter" class="com.alea.server.security.LanguageFilter" />
                <beans:bean id="userService" class="com.alea.server.services.UserService" />
                
            	<http use-expressions="true">
                	<intercept-url pattern="/login/login.htm*" filters="none" />
                    <intercept-url pattern="/secure/extreme/**" access="hasRole('ROLE_SUPERVISOR')"/>
                    <intercept-url pattern="/transport/**" access="isAuthenticated()" />
                    <intercept-url pattern="/**" access="permitAll" />
                    <intercept-url pattern="/images" access="permitAll" />
                    <intercept-url pattern="/css" access="permitAll" />
                    <form-login login-page="/front/login.htm" default-target-url="/index.htm" />
                    <logout logout-success-url="/index.htm" />
                    <remember-me />
                    <!-- Uncomment to limit the number of sessions a user can have -->
                    <session-management>
                        <concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
                    </session-management>
                    <custom-filter position="FORM_LOGIN_FILTER" ref="languageFilter" />
                </http>
            
                <authentication-manager>
                    <authentication-provider user-service-ref="userService">
                        <password-encoder hash="md5"/>      
                    </authentication-provider>
                </authentication-manager>
            
            
            </beans:beans>
            Here is my filter code:
            Code:
            package com.alea.server.security;
            
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;
            import org.springframework.security.core.Authentication;
            import org.springframework.security.core.AuthenticationException;
            import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
            
            public class LanguageFilter extends UsernamePasswordAuthenticationFilter {
            	
            	public static final Logger logger = LoggerFactory.getLogger(LanguageFilter.class);
            	
            	public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response) throws AuthenticationException {
            		if ( logger.isDebugEnabled() ) {
            			logger.debug("Language Filter");
            			logger.debug("Lang = " + request.getParameter("lang"));
            		}
            		
            		return super.attemptAuthentication(request, response);
            	}
            }

            Comment


            • #7
              Check the error message in the log. It is probably complaining because you have two filters at the "FORM_LOGIN" position - the default one (created by the <form-login> element) and your custom one. If you're replacing the filter created by <form-login> then you need to remove the element.

              Comment


              • #8
                Thanks for those replies

                I tryied to remove the extra default form-login, but now, the application loads properly and .... make a 404 error when I request a page.

                Strangely, there is no tomcat logging, except "The webapp is deployed successfully" ... And when I remove my custom filter , everything's fine again

                Comment


                • #9
                  What page are you trying to access that gives a 404 error? Are you absolutely sure there are no errors upon startup?

                  Comment


                  • #10
                    Every page gives a 404 error.
                    It's hard to belive that there is no error, but there is noting in the tomcat log files (catalina.log , stdout.log , manager.log and localhost.log ) ...

                    Comment


                    • #11
                      Seems like 100% true that something went wrong deploying the app then, or starting up Tomcat.

                      Comment


                      • #12
                        I agree, and I think it's linked to something in my applicationContext-security.xml file, as if I remove the custom filter lines (the beans:bean and the custom filter itself) and put the default filter back, everything's fine again...

                        Here is my current applicationContext-security.xml file:
                        Code:
                        <?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: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.0.xsd
                                                http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
                        
                            <global-method-security secured-annotations="enabled"  />
                            
                            <beans:bean id="languageFilter" class="com.alea.server.security.LanguageFilter" />
                            <beans:bean id="userService" class="com.alea.server.services.UserService" />
                            
                        	<http use-expressions="true">
                            	<intercept-url pattern="/login/login.htm*" filters="none" />
                                <intercept-url pattern="/secure/extreme/**" access="hasRole('ROLE_SUPERVISOR')"/>
                                <intercept-url pattern="/transport/**" access="isAuthenticated()" />
                                <intercept-url pattern="/**" access="permitAll" />
                                <intercept-url pattern="/images" access="permitAll" />
                                <intercept-url pattern="/css" access="permitAll" />
                                <custom-filter position="FORM_LOGIN_FILTER" ref="languageFilter" />
                                <logout logout-success-url="/index.htm" />
                                <remember-me />
                                <!-- Uncomment to limit the number of sessions a user can have -->
                                <session-management>
                                    <concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
                                </session-management> 
                            </http>
                        
                            <authentication-manager>
                                <authentication-provider user-service-ref="userService">
                                    <password-encoder hash="md5"/>      
                                </authentication-provider>
                            </authentication-manager>
                        
                        
                        </beans:beans>
                        Sme interesting thing : when I put the code of the UsernamePasswordAuthenticationFilter in my custom filter (just a copy paste at all), I get this error message at the startup:
                        Code:
                        org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: No AuthenticationEntryPoint could be established. Please make sure you have a login mechanism configured through the namespace (such as form-login) or specify a custom AuthenticationEntryPoint with the 'entry-point-ref' attribute  Offending resource: class path resource [applicationContext-security.xml] 	at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
                        Last edited by romain.vdk; Jul 20th, 2010, 01:18 AM.

                        Comment


                        • #13
                          Ok, Some new things:

                          I got this error now : java.lang.IllegalArgumentException: authenticationManager must be specified
                          at org.springframework.util.Assert.notNull(Assert.jav a:112)
                          at org.springframework.security.web.authentication.Ab stractAuthenticationProcessingFilter.afterProperti esSet(AbstractAuthenticationProcessingFilter.java: 153)

                          To arrive here, I just modified my xml (see previous post) like this :
                          <beans:bean id="entryPoint" class="org.springframework.security.web.authentica tion.LoginUrlAuthenticationEntryPoint" />
                          <http use-expressions="true" auto-config="false" entry-point-ref="entryPoint" >

                          My authenticationManager is set at the end, I don't see what's wrong ...

                          Comment


                          • #14
                            Are you sure you haven't inadvertently removed the applicationContext-security.xml reference from your web.xml file?

                            Comment


                            • #15
                              I'm sure of that. Last time I modified my web.xml file was a lot of days ago, to setup spring security ... Since when it has worked withe the first security.xml file, and when I modify it to add my custom filter, it doesn't work anymore.

                              Anyway, if you want to have a look at it, here it is:
                              Code:
                              <?xml version = '1.0' encoding = 'windows-1252'?>
                              <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
                                       version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
                                  <display-name>Alea</display-name>
                              
                                  <!-- Log4J Initialization Config -->
                                  <context-param>
                                      <param-name>log4jConfigLocation</param-name>
                                      <param-value>/WEB-INF/log4j.xml</param-value>
                                  </context-param>
                              
                                  <context-param>
                                      <param-name>log4jRefreshInterval</param-name>
                                      <param-value>1000</param-value>
                                  </context-param>
                              
                                  <!-- Log4J Initialization -->
                                  <listener>
                                      <listener-class>
                                          org.springframework.web.util.Log4jConfigListener
                                      </listener-class>
                                  </listener>
                              
                                  <!--
                                    - Location of the XML file that defines the root application context
                                    - Applied by ContextLoaderListener.
                                    -->
                                  <context-param>
                                      <param-name>contextConfigLocation</param-name>
                                      <param-value>
                                          classpath:/applicationContext-security.xml
                                      </param-value>
                                  </context-param>
                                  
                                  <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>
                              
                                  <!--
                                    - Loads the root application context of this web app at startup.
                                    - The application context is then available via
                                    - WebApplicationContextUtils.getWebApplicationContext(servletContext).
                                  -->
                                  <listener>
                                      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
                                  </listener>
                                 
                              
                                  <!-- Spring Initialization -->
                                  <servlet>
                                      <servlet-name>springWeb</servlet-name>
                                      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                                      <init-param>
                                          <param-name>contextConfigLocation</param-name>
                                          <param-value>
                                              classpath:/applicationContext.xml
                                              classpath:/repositoriesApplicationContext.xml
                                              classpath:/servicesApplicationContext.xml
                                              classpath:/webApplicationContext.xml
                                          </param-value>
                                      </init-param>
                                      <load-on-startup>1</load-on-startup>
                                  </servlet>
                                  <servlet-mapping>
                                      <servlet-name>springWeb</servlet-name>
                                      <url-pattern>*.gwt</url-pattern>
                                  </servlet-mapping>
                              
                                  <!-- Spring Initialization -->
                                  <servlet>
                                      <servlet-name>springMvc</servlet-name>
                                      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                                      <init-param>
                                          <param-name>contextConfigLocation</param-name>
                                          <param-value>
                                              classpath:/springMvcContext.xml
                                          </param-value>
                                      </init-param>
                                      <load-on-startup>1</load-on-startup>
                                  </servlet>
                                  <!-- HTM needed because html extension is used by GWT -->
                                  <servlet-mapping>
                                      <servlet-name>springMvc</servlet-name>
                                      <url-pattern>*.htm</url-pattern>
                                  </servlet-mapping>
                                  <servlet-mapping>
                                      <servlet-name>springMvc</servlet-name>
                                      <url-pattern>*.xml</url-pattern>
                                  </servlet-mapping>
                              
                              </web-app>

                              Comment

                              Working...
                              X