Announcement Announcement Module
Collapse
No announcement yet.
Need to allow auto-login Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Need to allow auto-login

    I have a legacy application that during a migration period, I need to allow auto-login into this new Spring Security application and would like some help to understand how I could do this in the new Spring Security?

  • #2
    Use a Pre-auth provider

    If you read the documentation, you will find information on the PreAuthenticatedAuthenticationProvider. A sample config is as follows:


    <beans:bean id="xyzUserDetailsService" class ="com.xyzcorp.test.dao.UserDetailDao"/>

    <authentication-provider user-service-ref='xyzUserDetailsService'>
    </authentication-provider>


    <beans:bean id="singleSignOnFilter"
    class="com.xyzcorp.test.auth.SingleSignOn">
    <custom-filter position="PRE_AUTH_FILTER" />
    <beansroperty name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

    <beans:bean id="preauthAuthProvider"
    class="org.springframework.security.providers.prea uth.PreAuthenticatedAuthenticationProvider">
    <custom-authentication-provider />
    <beansroperty name="preAuthenticatedUserDetailsService">
    <beans:bean id="userDetailsServiceWrapper"
    class="org.springframework.security.userdetails.Us erDetailsByNameServiceWrapper">
    <beansroperty name="userDetailsService" ref="xyzUserDetailsService"/>
    </beans:bean>
    </beansroperty>
    </beans:bean>


    <authentication-manager alias="authenticationManager" />

    You will have to implement UserDetailDao and SingleSignOn

    Comment


    • #3
      I started to create the entry like:

      Code:
       
       
          <beans:bean id="jdbcUserDetailService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
              <beans:property name="dataSource" ref="dataSource" />
              <beans:property name="usersByUsernameQuery"
                  value="SELECT cr.username, cr.password, 'true' FROM plat.dbo.customer cr WHERE cr.username = ?" />
              <beans:property name="authoritiesByUsernameQuery"
                  value="SELECT customer.username, role.name as authority FROM plat.dbo.customer customer, plat.dbo.role role, plat.dbo.customer_role customer_role WHERE customer_role.customer_username = customer.username AND customer_role.role_id = role.id AND customer.username = ?" />
          </beans:bean>
       
          <!-- Single Sign-On filtering -->
       
          <authentication-provider user-service-ref='jdbcUserDetailService'>
          </authentication-provider>
          <beans:bean id="singleSignOnFilter"
              class="com.servepath.security.SingleSignOnFilter">
              <custom-filter position="PRE_AUTH_FILTER" />
              <beans:property name="authenticationManager" ref="authenticationManager" />
          </beans:bean>
          <beans:bean id="preauthAuthProvider"
                      class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
              <custom-authentication-provider />
              <beans:property name="preAuthenticatedUserDetailsService">
                  <beans:bean id="userDetailsServiceWrapper"
                          class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
                      <beans:property name="userDetailsService" ref="jdbcUserDetailService"/>
                  </beans:bean>
              </beans:property>
          </beans:bean>
          <authentication-manager alias="authenticationManager" />
      But I keep getting this error:

      Code:
      SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
      org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_filterChainProxy': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_filterChainList': Cannot create inner bean '(inner bean)' of type [org.springframework.security.config.OrderedFilterBeanDefinitionDecorator$OrderedFilterDecorator] while setting bean property 'filters' with key [11]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#6': Cannot resolve reference to bean 'singleSignOnFilter' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'singleSignOnFilter' defined in ServletContext resource [/WEB-INF/applicationContext-security.xml]: Initialization of bean failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'authenticationManager' of bean class [com.servepath.security.SingleSignOnFilter]: No property 'authenticationManager' found
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:470)
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:404)
       at java.security.AccessController.doPrivileged(Native Method)
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:375)
       at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:263)
       at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:170)
       at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:260)
       at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:184)
       at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:163)
       at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:430)
       at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
       at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
       at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:254)
       at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:198)
       at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
       at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
       at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
       at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
       at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
       at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
       at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
       at org.apache.catalina.core.StandardService.start(StandardService.java:516)
       at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
       at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
       at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

      Comment


      • #4
        In the traceback it's saying "No property 'authenticationManager' found". That implies to me that your com.servepath.security.SingleSignOnFilter class doesn't have a setter for that.

        Comment


        • #5
          I got the filter to work and pick up the parameters, but now the forward does not seem to work:

          Code:
              public void doFilter(ServletRequest request, ServletResponse response,
                                  FilterChain chain)
              throws IOException, ServletException {
                  //chain.doFilter(wrapRequest(request), response);
          
                  if (!(request instanceof HttpServletRequest)) {
                      chain.doFilter(request, response);
                  }
          
                  String userId = request.getParameter("username");
                  String password = request.getParameter("password");
          
                  if(userId == null || password == null){
                      chain.doFilter(request, response);
                  }
                  else{
          
                      System.out.println("=============================================");
                      System.out.println("userId: " + userId);
                      System.out.println("password: " + password);
                      System.out.println("=============================================");
                      //Test: http://localhost:8888/myservepath/services/index.html?username=13011&password=1234
          
                      String acegiUrl = "/j_spring_security_check?j_username="
                                          + userId
                                          + "&j_password="
                                          + password;
          
                      if (config != null) {
                          config.getServletContext().getRequestDispatcher(acegiUrl).forward(request, response);
                          return;
          
                      }
          
                      chain.doFilter(request, response);
                  }
          
              }
          What can I do to forward this request?

          Comment


          • #6
            Has anyone else done this? Can someone please help me on this? It is much appreciated...

            Comment


            • #7
              Here is my code

              Here is my code for Single Sign On. If I return a String instead of null in the method getPreAuthenticatedPrincipal, the sign in will work automatically. I wish someone would help me out with http-https switching - it is much appreciated too


              package com.nonamecorp.nonameproject.auth;

              import javax.servlet.http.Cookie;
              import javax.servlet.http.HttpServletRequest;
              import javax.servlet.http.HttpServletResponse;

              import org.springframework.security.Authentication;
              import org.springframework.security.AuthenticationExcepti on;
              import org.springframework.security.ui.FilterChainOrder;
              import org.springframework.security.ui.preauth.AbstractPr eAuthenticatedProcessingFilter;
              import org.springframework.security.ui.preauth.PreAuthent icatedCredentialsNotFoundException;

              public class SingleSignOn extends AbstractPreAuthenticatedProcessingFilter {

              /**
              * Read and returns the header named by <tt>principalRequestHeader</tt> from the request.
              *
              * @throws PreAuthenticatedCredentialsNotFoundException if the header is missing
              */
              protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
              Cookie cookies[] = request.getCookies();
              if (cookies != null)
              {
              for (int i = 0; i < cookies.length; i++) {
              System.out.println("Cookie " + cookies[i].getName() + "=" + cookies[i].getValue() + ", " + cookies[i].getSecure() + ", " + cookies[i].getPath());
              }
              }
              return null;
              }

              /**
              * Credentials aren't usually applicable.
              */
              protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {

              return "N/A";
              }

              protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) {
              super.successfulAuthentication(request, response, authResult);
              }

              protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
              super.unsuccessfulAuthentication(request, response, failed);
              Cookie c = new Cookie("testcc", "value");
              c.setMaxAge(14 * 24 * 60 * 60);
              response.addCookie(c);
              System.out.println("Test failed authentication");
              }

              public int getOrder() {
              return FilterChainOrder.PRE_AUTH_FILTER;
              }
              }

              Comment


              • #8
                Section 16, page 57 of the Spring Security Reference guide explains how to handle pre-authentication.

                http://static.springframework.org/sp...reference.html

                Maybe that would work for you?

                Comment


                • #9
                  I used your class, then added a check to return a String as you suggested:
                  Code:
                      protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
                          Cookie cookies[] = request.getCookies();
                          if (cookies != null){
                              for (int i = 0; i < cookies.length; i++) {
                                  System.out.println("Cookie "
                                  + cookies[i].getName() + "=" + cookies[i].getValue()
                                  + ", " + cookies[i].getSecure()
                                  + ", " + cookies[i].getPath());
                              }
                          }
                  
                          String userId = request.getParameter("username");
                          String password = request.getParameter("password");
                  
                          System.out.println("=============================================");
                          System.out.println("userId: " + userId);
                          System.out.println("password: " + password);
                          System.out.println("=============================================");
                  
                          if(userId != null && password != null){
                              return "logged in";
                          } else{
                              return null;
                          }
                      }
                  But I still get directed to the login screen, and get this in my logs:

                  Code:
                  Cookie JSESSIONID=B208365ED0E25E8433E94CB12A20578A, false, null
                  =============================================
                  userId: user1
                  password: p@ssord
                  =============================================
                  Test failed authentication

                  Comment


                  • #10
                    It works fine for me

                    Maybe you should post your security.xml file for us to look at

                    Comment


                    • #11
                      Code:
                      <?xml version="1.0" encoding="UTF-8"?>
                      
                      <!--
                        - Sample namespace-based configuration
                        -
                        - $Id: applicationContext-security.xml 3019 2008-05-01 17:51:48Z luke_t $
                        -->
                      <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-2.0.xsd
                                              http://www.springframework.org/schema/security
                                               http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
                      
                          <global-method-security secured-annotations="enabled">
                              <!-- AspectJ pointcut expression that locates our "post" method and applies security that way
                              <protect-pointcut expression="execution(* bigbank.*Service.post*(..))" access="ROLE_TELLER"/>
                              -->
                          </global-method-security>
                      
                      
                      
                          <!--<beans:bean id="secureResourceFilter" class="com.servepath.security.SingleSignOnFilter" />-->
                      
                          <http auto-config="true" access-denied-page="/view/error/403.jsp">
                              <intercept-url pattern="/login.jsp*" filters="none"/>
                              <intercept-url pattern="/login.html*" filters="none"/>
                      
                              <intercept-url pattern="/view/admin/**" access="ROLE_ADMIN"/>
                              <intercept-url pattern="/services/**" access="ROLE_CUSTOMER"/>
                      
                      
                              <!-- All of this is unnecessary if auto-config="true" -->
                              <form-login login-page="/login.html" authentication-failure-url="/login.html?login_error=1" default-target-url="/services/index.html" />
                      
                              <!--anonymous / -->
                      
                              <!--http-basic / -->
                      
                              <logout logout-success-url="/index.html"/>
                      
                              <!--remember-me /-->
                      
                              <!--servlet-api-integration /-->
                      
                              <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
                      
                           </http>
                      
                      
                          <!--<authentication-provider>
                              <jdbc-user-service data-source-ref="dataSource"
                              users-by-username-query="SELECT cr.username, cr.password, 'true' FROM plat.dbo.customer cr WHERE cr.username = ?"
                      
                              authorities-by-username-query="SELECT customer.username, role.name as authority FROM plat.dbo.customer customer, plat.dbo.role role, plat.dbo.customer_role customer_role WHERE customer_role.customer_username = customer.username AND customer_role.role_id = role.id AND customer.username = ?"/>
                          </authentication-provider>-->
                      
                      
                      
                          <!-- Single Sign-On filtering -->
                          <!--
                          Test with this URL:
                          http://localhost:8888/myservepath/services/index.html?username=13011&password=st@g3!
                          -->
                      
                          <beans:bean id="jdbcUserDetailService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
                              <beans:property name="dataSource" ref="dataSource" />
                              <beans:property name="usersByUsernameQuery"
                                  value="SELECT cr.username, cr.password, 'true' FROM plat.dbo.customer cr WHERE cr.username = ?" />
                              <beans:property name="authoritiesByUsernameQuery"
                                  value="SELECT customer.username, role.name as authority FROM plat.dbo.customer customer, plat.dbo.role role, plat.dbo.customer_role customer_role WHERE customer_role.customer_username = customer.username AND customer_role.role_id = role.id AND customer.username = ?" />
                          </beans:bean>
                      
                          <!--<beans:bean id="jdbcUserDetailService" class ="com.xyzcorp.test.dao.UserDetailDao"/>-->
                      
                          <authentication-provider user-service-ref='jdbcUserDetailService'>
                          </authentication-provider>
                      
                          <beans:bean id="singleSignOnFilter"
                              class="com.servepath.security.SingleSignOnFilter">
                      
                              <custom-filter position="PRE_AUTH_FILTER" />
                              <beans:property name="authenticationManager" ref="authenticationManagerAlias" />
                          </beans:bean>
                      
                          <beans:bean id="preauthAuthProvider"
                                      class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
                              <custom-authentication-provider />
                      
                              <beans:property name="preAuthenticatedUserDetailsService">
                                  <beans:bean id="userDetailsServiceWrapper"
                                          class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
                                      <beans:property name="userDetailsService" ref="jdbcUserDetailService"/>
                                  </beans:bean>
                              </beans:property>
                          </beans:bean>
                      
                          <authentication-manager alias="authenticationManagerAlias"/>
                      
                      
                      
                      </beans:beans>

                      Comment


                      • #12
                        It looks like you are forwarding to a URL and expecting the filter chain to pick it up, but this won't happen unless you have your web.xml set up appropriately.

                        http://static.springframework.org/sp...ity-on-forward

                        Do you get a 404 for j_spring_security_check? Debug logging information is usually the best way of diagnosing this kind of thing.

                        Comment


                        • #13
                          I added my filter to my web.xml:
                          Code:
                              <filter>
                                  <filter-name>singleSignOnSecurityFilterChain</filter-name>
                                  <filter-class>com.servepath.security.SingleSignOnFilter</filter-class>
                              </filter>
                              <filter-mapping>
                                  <filter-name>singleSignOnSecurityFilterChain</filter-name>
                                  <url-pattern>/*</url-pattern>
                                  <dispatcher>REQUEST</dispatcher>
                                  <dispatcher>INCLUDE</dispatcher>
                                  <dispatcher>FORWARD</dispatcher>
                              </filter-mapping>
                          So on a url without a username & password on the querystring I get this in the logs:
                          Code:
                          **********************************************
                          **********************************************
                          **********************************************
                          **********************************************
                          return 'null'
                          Cookie JSESSIONID=E0A1CB23F431BAB7B4DBE16949535AA8, false, null
                          return 'null'
                          return 'null'
                          return 'null'
                          Then I used "http://localhost:8888/myservepath/services/index.html?username=13011&password=p@ssword"

                          and got:

                          Code:
                          **********************************************
                          return 'null'
                          Cookie testcc=value, false, null
                          Cookie JSESSIONID=E0A1CB23F431BAB7B4DBE16949535AA8, false, null
                          =============================Aug 8, 2008 10:57:16 AM org.apache.catalina.core.StandardWrapperValve invoke
                          SEVERE: Servlet.service() for servlet Faces Servle================
                          userId: 13011
                          password: p@ssword
                          =============================================
                          ******************************t threw exception
                          java.lang.NullPointerException
                              at org.springframework.security.ui.preauth.AbstractPreAuthenticatedProcessin****************
                          return 'logged in'
                          gFilter.doAuthenticate(AbstractPreAuthenticatedProcessingFilter.java:87)
                              at org.springframework.security.ui.preauth.AbstractPreAuthenticatedProcessingFilter.doFilterHttp(AbstractPreAuthenticatedProcessingFilter.java:58)
                              at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
                              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                              at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
                              at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
                              at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
                              at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
                              at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
                              at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:568)
                              at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                              at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
                              at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
                              at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
                              at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                              at java.lang.Thread.run(Thread.java:595)

                          Comment


                          • #14
                            So look at the line number:

                            http://static.springframework.org/sp...Filter.html#87

                            which would indicate that the authenticationManager is null. Unless the filter is loaded as part of the application context, it won't be initialized properly. Use a DelegatingFilterProxy rather than defining it directly in web.xml.

                            Comment


                            • #15
                              I already had this in my web.xml:

                              Code:
                                    <filter>
                                      <filter-name>singleSignOnSecurityFilterChain</filter-name>
                                      <filter-class>com.servepath.security.SingleSignOnFilter</filter-class>
                                  </filter>
                                  <filter-mapping>
                                      <filter-name>singleSignOnSecurityFilterChain</filter-name>
                                      <url-pattern>/*</url-pattern>
                                      <dispatcher>REQUEST</dispatcher>
                                      <dispatcher>INCLUDE</dispatcher>
                                      <dispatcher>FORWARD</dispatcher>
                                  </filter-mapping>
                              
                              
                                  <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>
                              So I can delete my SingleSignOnFilter again, but I still do not know how to make the user Auto-Signed in as per my requirements.

                              Comment

                              Working...
                              X