Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Implementing Relogin with Spring Security

    Hi -- I'm trying to figure out how to implement Spring Security 4 relogin with "v9.1p_2015-02-07/Pro Deployment", but I'm losing the transaction somehow. I've read the example from 5 years ago:
    http://forums.smartclient.com/showthread.php?t=9633
    but that was implemented with Smart GWT, and I can't find a good example for SmartClient. Also, perhaps Spring Security has changed since then.

    Here's my login.jsp:

    Code:
    <%@ taglib uri="/WEB-INF/iscTaglib.xml" prefix="isomorphic" %>
    <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
    <!DOCTYPE html>
    <HTML><HEAD><TITLE>My Login Page</TITLE>
    <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Core.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Foundation.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Containers.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Grids.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Forms.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_DataBinding.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/login/reloginFlow.js></SCRIPT>
    <SCRIPT SRC=./isomorphic/skins/Graphite/load_skin.js></SCRIPT>
    </HEAD><BODY>
    
    <SCRIPT>
    isc.RPCManager.credentialsURL = "/secured/loginSuccessMarker.html";
    isc.showLoginDialog(function (credentials, dialogCallback){
          var request = isc.RPCRequest.create({
                actionURL: "/secured/login",
                httpMethod: "POST",
                params: {username: credentials.username, 
                         password: credentials.password},
                useSimpleHttp: true,
                containsCredentials: true,
                callback: function(rpcResponse,rpcRequest){
                   var success = rpcResponse.status == isc.RPCResponse.STATUS_SUCCESS;
                   dialogCallback(success);
                   if(success){
                      window.location = "index.jsp";
                   }
                },
             });
          isc.RPCManager.sendRequest(request);
       });
    </SCRIPT>
    
    <SCRIPT>//'"]]>>isc_loginRequired
    //
    // Embed this whole script block VERBATIM into your login page to enable
    // SmartClient RPC relogin.
    //=======    
    
    
    
    if (!window.isc && document.domain && document.domain.indexOf(".") != -1 
    	&& !(new RegExp("^(\\d{1,3}\\.){3}\\d{1,3}$").test(document.domain))) 
    {
        
        var set = false;
        while (document.domain.indexOf(".") != -1) {
            try {
                if (window.opener && window.opener.isc) break;
                if (window.top.isc) break;
                
                if (!set) { document.domain = document.domain; set = true; }
                else { document.domain = document.domain.replace(/.*?\./, ''); }
            } catch (e) {
                try {
                    if (!set) { document.domain = document.domain; set = true }
                    else { document.domain = document.domain.replace(/.*?\./, ''); }
                } catch (ee) {
                    break;
                }
            }
        } 
    }
    
    var isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
    if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginRequired", [window]);
    </SCRIPT>
    
    </BODY>
    </HTML>
    and bootstrapped from one of the Spring Security samples (and not carefully cleaned up yet), my WEB-INF/spring/security.xml:

    Code:
    <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.xsd">
    
      <debug />
      <http pattern="/isomorphic/system/**" security="none"/>
      <http pattern="/isomorphic/locales/**" security="none"/>
      <http pattern="/isomorphic/login/*js" security="none"/>
      <http pattern="/isomorphic/skins/**" security="none"/>
      <http pattern="/src/**" security="none"/>
      <http pattern="/js/**" security="none"/>
      <http pattern="/css/**" security="none"/>
      <http pattern="/images/**" security="none"/>
      <http pattern="/loginDialog.js" security="none"/>
    
      <http>
        <intercept-url pattern="/login.jsp*" access="permitAll"/>                                                                                         
        <intercept-url pattern="/**" access="isAuthenticated()" />                                                                                        
        <intercept-url pattern="/isomorphic/IDACall*" access="isAuthenticated()" />                                                                       
        <intercept-url pattern="/isomorphic/login/loginSuccessMarker.html" access="isAuthenticated()" /> 
        <csrf disabled="true"/>
        <form-login login-page="/login.jsp" />
        <logout delete-cookies="JSESSIONID" />
        <remember-me />
      </http>
    
    	<!--
    	Usernames/Passwords are
    		rod/koala
    		dianne/emu
    		scott/wombat
    		peter/opal
    	-->
    	<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    
    	<authentication-manager>
    		<authentication-provider>
    			<password-encoder ref="encoder"/>
    			<user-service>
    				<user name="rod" password="$2a$10$75pBjapg4Nl8Pzd.3JRnUe7PDJmk9qBGwNEJDAlA3V.dEJxcDKn5O" authorities="supervisor, user, teller" />
    				<user name="dianne" password="$2a$04$bCMEyxrdF/7sgfUiUJ6Ose2vh9DAMaVBldS1Bw2fhi1jgutZrr9zm" authorities="user,teller" />
    				<user name="scott" password="$2a$06$eChwvzAu3TSexnC3ynw4LOSw1qiEbtNItNeYv5uI40w1i3paoSfLu" authorities="user" />
    				<user name="peter" password="$2a$04$8.H8bCMROLF4CIgd7IpeQ.tcBXLP5w8iplO0n.kCIkISwrIgX28Ii" authorities="user" />
    			</user-service>
    		</authentication-provider>
    	</authentication-manager>
    
    </beans:beans>
    Does my login.jsp look more or less correct? I disabled CSRF tokens for now because I want to figure out relogin before adding that. As far as I can tell, I'm able to login the way it's supposed to work.

    I can use my page to relogin too... although I'm losing my transaction somehow. I put a print statement inside handleLoginRequired and
    Code:
    var transaction = this.getTransaction(transactionNum);                                                                                        
    console.log("transaction:",transaction);
    is printing null. I can't figure out what's going on with isc.showConsole() because when my session times out, the page redirects to login.jsp when an IDACall gets access denied, and everything in the ISC console gets cleared. I get the login dialog from my login.jsp and not the expected relogin dialog in reloginFlow.js (i.e. the login dialog still works, but I lost my transaction).

    Here's my Catalina log near the redirect:
    Code:
    16:10:28.855 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /isomorphic/IDACall?isc_rpc=1&isc_v=v9.1p_2015-02-07&isc_xhr=1; Attributes: [isAuthenticated()]
    16:10:28.856 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 5FC2D60009E5DD456B06D30921520331; Granted Authorities: ROLE_ANONYMOUS
    16:10:28.856 [http-bio-8080-exec-27] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@772e499b, returned: -1
    16:10:28.857 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
    org.springframework.security.access.AccessDeniedException: Access is denied
    	at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) ~[spring-security-core-4.0.1.CI-SNAPSHOT.jar:na]
    ...
    16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.s.HttpSessionRequestCache - DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/secured/isomorphic/IDACall?isc_rpc=1&isc_v=v9.1p_2015-02-07&isc_xhr=1]
    16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Calling Authentication entry point.
    16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'http://localhost:8080/secured/login.jsp'
    16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
    16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

    On a related note... I'm not sure how to handle loginSuccessMarker.html with Spring Security. In your documentation, you said I should be able to either POST credentials to loginSuccessMarker.html or have my authentication system return the contents of loginSuccessMarker.html as a part of a successful response. I can't find an option in Spring Security for the former option. In the Smart GWT examples, the later approach was taken and loginSuccessMarker was embedded as a string in some Java code, but I don't see how to do this from SmartClient. For example, there doesn't appear to be an appropriate place for these contents in security.xml for example.

    One idea I had was for relogin to take two POST steps. The first would target /login with the credentials, and the second would target loginSuccessMarker.html. That's probably not the simplest approach. It's also irrelevant if the transaction number was lost as I described above.



    What am I misunderstanding?
    Thanks so much!!
    Last edited by nitroamos; 28 May 2015, 08:27. Reason: improved security.xml

    #2
    I'd appreciate any advice to help me track down the problem! Here's a quick summary:

    1. I believe I've followed the instructions correctly, but I'm losing the transaction during relogin.

    2. I'm not using Smart GWT. I couldn't figure out how to implement loginSuccessMarker.html with Spring Security 4.

    Comment


      #3
      I've spent a few days upgrading to Spring Security 4.0.3 and thought I would share my findings with the community. Note that my upgrade to Spring 4 is based on the fine work described in post

      http://forums.smartclient.com/showthread.php?t=9633

      I make no claims that this is a perfect implementation nor am I a Spring Security expert. I post this with the sole intent of helping other smartGWT users make the transition to Spring 4. Use at your own risk.


      Changes to Entry Point to comply with Spring Security 4: CREDENTIALS_URL changed to /login. J_PASSWORD variable changed to "password". J_USERNAME variable changed to "username".


      Code:
      public class WebGUI implements EntryPoint {
      private static final String CREDENTIALS_URL="/login";
      private LoginWindow loginWindow;
      private LoginForm loginForm;
      
      
      public void onModuleLoad() {
      
      RPCManager.setLoginRequiredCallback(new LoginRequiredCallback(){
                  @Override
                  public void loginRequired(int i, RPCRequest rpcRequest, RPCResponse rpcResponse) {
                      raiseLoginWindow();
                  }
              });
      
      }
      
      protected void raiseLoginWindow(){
               if(loginWindow==null)
                   loginWindow=new LoginWindow();
               if(!(loginWindow.isVisible() && loginWindow.isDrawn())){
                   loginForm.clearValues();
                   loginForm.focusInItem("username");
               }
               loginWindow.show();
               loginWindow.bringToFront();    
          }
      
      public class LoginWindow extends Window {
               
              private static final int PADDING = 50;
              private static final int LOGIN_LAYOUT_WIDTH = 533;
              private static final int SPACER_HEIGHT = 180;
              private static final String LOGIN_BACKGROUND_PNG = "login_background.png";
              private static final int LOGIN_HEIGHT = 487;
              private static final int LOGIN_WIDTH = 545;
              private static final int LOGIN_LEFT = 400;
              private static final int LOGIN_TOP = 150;
      
              public LoginWindow(){
                  this.setTop(LOGIN_TOP);
                  this.setLeft(LOGIN_LEFT);  
                  this.setWidth(LOGIN_WIDTH);
                  this.setHeight(LOGIN_HEIGHT);
                  this.setShowHeader(false);
                  //this.setBackgroundImage("login_background.png");
                  //this.setMargin(120);
                  
                  VLayout loginLayout = new VLayout();
                  loginLayout.setBackgroundImage(LOGIN_BACKGROUND_PNG);       
                  loginLayout.setWidth(LOGIN_LAYOUT_WIDTH);          
                  LayoutSpacer spacer = new LayoutSpacer();
                  spacer.setHeight(SPACER_HEIGHT);
                  loginLayout.addMember(spacer);
                  
                  loginForm=new LoginForm(CREDENTIALS_URL);
                  loginForm.setPadding(PADDING);
                  setShowModalMask(true);
                  //centerInPage();
                  setShowCloseButton(false);
                  setShowMinimizeButton(false);
                  setIsModal(true);
                  //setAutoSize(true);
                  loginLayout.addMember(loginForm);          
                  addItem(loginLayout);
              }
          }
      
          private class LoginForm extends DynamicForm {
              private static final int COLUMN_2_WIDTH = 125;
              private static final int COLUMN_1_WIDTH = 150;
              private static final int NUMBER_OF_COLUMNS = 2;
              private static final int LOGIN_FORM_WIDTH = 520;
              //private static final String J_PASSWORD = "j_password";
              //private static final String J_USERNAME = "j_username";
              private static final String J_PASSWORD = "password";
              private static final String J_USERNAME = "username";
              private static final String ENTER = "Enter";
              private static final String PASSWORD = "password";
              private static final String USERNAME = "username";
              private static final String FORM_CELL_ERROR = "formCellError";
              private static final String LOGIN_FAILURE = "loginFailure";
              private String credentialsURL;
      
              public LoginForm(String credentialsURL){
                  //this.setBackgroundColor("gray");
                  this.setWidth(LOGIN_FORM_WIDTH);
                  this.setNumCols(NUMBER_OF_COLUMNS);
                  this.setColWidths(COLUMN_1_WIDTH, COLUMN_2_WIDTH); 
                   
                  this.credentialsURL=credentialsURL;
                  BlurbItem blurbItem=new BlurbItem(LOGIN_FAILURE);
                  blurbItem.setVisible(false);
                  blurbItem.setColSpan(2);
                  blurbItem.setDefaultValue(constants.Invalid_User_Name_or_Password());
                  blurbItem.setCellStyle(FORM_CELL_ERROR);
              
                  TextItem textItem=new TextItem(USERNAME);
                  //textItem.setTitleStyle("loginFailure");
                  textItem.setTitle(constants.UserName());
                  textItem.setTitleOrientation(TitleOrientation.LEFT);
                  textItem.addKeyPressHandler(new KeyPressHandler(){
                      @Override
                      public void onKeyPress(KeyPressEvent keyPressEvent) {
                          if(keyPressEvent.getKeyName().equals(ENTER)){
                              focusInItem(PASSWORD);
                          }
                      }
                  });
                  PasswordItem passwordItem=new PasswordItem(PASSWORD);
                  passwordItem.setTitle(constants.Password());
                  passwordItem.setTitleOrientation(TitleOrientation.LEFT);
                  passwordItem.addKeyPressHandler(new KeyPressHandler(){
                      @Override
                      public void onKeyPress(KeyPressEvent keyPressEvent) {
                          if(keyPressEvent.getKeyName().equals(ENTER)){
                              doLogin();
                          }
                      }
                  });
                    
                  ButtonItem buttonItem=new ButtonItem(constants.Login());
                  buttonItem.setAlign(Alignment.RIGHT);
                   buttonItem.addClickHandler(new ClickHandler(){
                      @Override
                      public void onClick(ClickEvent clickEvent) {
                          doLogin();
                      }
                  });
                  setFields(blurbItem, textItem,passwordItem,buttonItem);
              }
      
              public void doLogin(){
                  RPCRequest request=new RPCRequest();
                  request.setContainsCredentials(true);
                  request.setActionURL(credentialsURL);
                  request.setUseSimpleHttp(true);
                  request.setShowPrompt(false);
                  Map<String,String> params=new HashMap<String,String>();
                  final String userName = getValueAsString(USERNAME);
                  params.put(J_USERNAME,getValueAsString(USERNAME));
                  params.put(J_PASSWORD,getValueAsString(PASSWORD));
                  request.setParams(params);
                  RPCManager.sendRequest(request,new RPCCallback(){
                      @Override
                      public void execute(RPCResponse response, Object rawData, RPCRequest request) {
                          clearValues();
                          if(response.getStatus()==RPCResponse.STATUS_SUCCESS){
                              hideItem(LOGIN_FAILURE);
                              
                              AuthService.CommandApp.getInstance().retrieveUsername(new AsyncCallback<String>(){
      
                                  @Override
                                  public void onFailure(Throwable caught) {
                                      Log.warn("Unable to retrieve user name.  Logged in user label on toolbar will be blank");            
                                  }
      
                                  @Override
                                  public void onSuccess(String result) {
                                       setLoggedInUser(result);
                                       getMain().setOpacity(100);
                                  }
                                  
                              });
                                                                 
                              
                              RPCManager.resendTransaction();
                              loginWindow.hide();
                          }else if(response.getStatus()==RPCResponse.STATUS_LOGIN_INCORRECT){
                              Log.warn("Login failed");
                              showItem(LOGIN_FAILURE);
                          }else if(response.getStatus()==RPCResponse.STATUS_MAX_LOGIN_ATTEMPTS_EXCEEDED){
                              SC.warn("Max login attempts exceeded.");
                          }
                          focusInItem(USERNAME);
                      }
                  });
              }
          }
      Below is a logout hyperlink that I have enabled in another part of my smartGWT gui. It completes a Spring security logout, sets the opacity of the main window to 2 so it is "invisible", and raises the logout window again.

      Code:
      ...
      private static final String LOGOUT_URL="/logout";
      
      private Canvas getLogoutLink(){
              DynamicForm genericHyperlinkForm = new DynamicForm();
              genericHyperlinkForm.setNumCols(1);
              genericHyperlinkForm.setColWidths(110);
              LinkItem logoutLink = new LinkItem();
              logoutLink.setShowTitle(false);
              logoutLink.setWidth(100);
              logoutLink.setAlign(Alignment.LEFT);
              logoutLink.setLinkTitle(constants.Logout());
              logoutLink.setTooltip(constants.Logout_of_Atlantic());
      
              logoutLink.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {
      
                  @Override
                  public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
                      Log.info("Responding to Logout Hyperlink");
                      doLogOut();
                      webGUI.raiseLoginWindow();
                      webGUI.getMain().setOpacity(2);
                      
                  }
                  });  //  end on click
           
               
              genericHyperlinkForm.setFields(logoutLink);
              genericHyperlinkForm.setSize("125px", "20px");
              return genericHyperlinkForm;
                  
          }
      
      public void doLogOut(){
              Log.info("Managing logout.  Logout url is "+LOGOUT_URL);
               RPCRequest request=new RPCRequest();
              // request.setContainsCredentials(true);
               request.setActionURL(LOGOUT_URL);
               request.setUseSimpleHttp(true);
               request.setShowPrompt(false);     
               RPCManager.sendRequest(request,new RPCCallback(){
                   @Override
                   public void execute(RPCResponse response, Object rawData, RPCRequest request) {
                      
                       if(response.getStatus()==RPCResponse.STATUS_SUCCESS){
                          Log.info("Logged out");
                          
                         
                           
                       }else {
                           Log.warn("Log Out Failed.");
                       
                       }
                    }
               });
           
              
          }
      There are no changes required to the BiztrackAuthenticationEntryPoint, BiztrackAuthenticationFailureHandler, BiztrackAuthenticationSuccessHandler, BiztrackConcurrentSessionFilter, BiztrackInvalidSessionHandler, BiztrackMarkerResponseHandler or InvalidSessionHandler described by the original Spring 3 Security post above.

      My Spring applicationcontext.xml. Note that I have renamed many of the original "biztrack" classes to "Atlantic" to conform with my application naming conventions. Passwords are encoded using Spring 4's upgraded bcrypt algorithm. I obtain the user and password from a custom user details service that looks up the info from a Mongo database. Key changes from the original Spring 3 Security post include :

      Disabling csrf.
      Adding <logout> information pointing to the url to go to upon successful logout.
      Disabling content-type-options which caused problems in the chrome browser
      Specifying the bcrypt decoder
      Adding my custom mongo UserDetailsService

      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.xsd
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
      
      
          <!--    must disable spring csrf support for smartgwt to work    -->
            <http entry-point-ref="authenticationEntryPoint" use-expressions="false">
              <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter"/>
              <custom-filter position="FORM_LOGIN_FILTER" ref="formLoginFilter"/>
              <anonymous enabled="false"/>
              <csrf disabled="true"/>
              <intercept-url pattern="/Atlantic/sc/IDACall*" access="ROLE_USER"/>
              <access-denied-handler ref="accessDeniedHandler"/>
              <session-management session-authentication-strategy-ref="sessionAuthenticationStrategy"/>
              <logout invalidate-session="true" logout-success-url="/Atlantic.html"/>
              
              <headers defaults-disabled="true">
                  <cache-control/>
                  <hsts />
                  <xss-protection/>
                  <frame-options/>
                  <!--   disable the content type options below so Atlantic works in Chrome-->
                  <!--   >content-type-options/-->
              </headers>
              
          </http>
          
          
          <authentication-manager alias="authenticationManager">
              <authentication-provider ref="daoAuthenticationProvider"/>
            </authentication-manager>
         
            
            <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
       
        
          <beans:bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
              <beans:property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy"/>
              <beans:property name="authenticationManager" ref="authenticationManager"/>
              <beans:property name="authenticationSuccessHandler">
                  <beans:bean class="com.atlanticds.server.Authentication.AtlanticAuthenticationSuccessHandler"/>
              </beans:property>
              <beans:property name="authenticationFailureHandler">
                  <beans:bean class="com.atlanticds.server.Authentication.AtlanticAuthenticationFailureHandler"/>
              </beans:property>
          </beans:bean>
      
          <beans:bean id="authenticationEntryPoint"  class="com.atlanticds.server.Authentication.AtlanticAuthenticationEntryPoint"/>
      
          <beans:bean id="accessDeniedHandler"  class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
              <beans:property name="errorPage" value="/accessDenied.htm"/>
          </beans:bean>
      
          <beans:bean id="concurrencyFilter" class="com.atlanticds.server.Authentication.AtlanticConcurrentSessionFilter">
              <beans:property name="sessionRegistry" ref="sessionRegistry"/>
              <beans:property name="invalidSessionHandler">
                  <beans:bean class="com.atlanticds.server.Authentication.AtlanticInvalidSessionHandler"/>
              </beans:property>
          </beans:bean>
      
          <beans:bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
              <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
              <beans:property name="maximumSessions" value="1"/>
          </beans:bean>
          
          <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
           
          <beans:bean id="customAuthListener"    class="com.atlanticds.server.Authentication.CustomAuthListener" />
          
          
           
          <!--     Spring authentication for login   -->
          <beans:bean id="mongoUserDetailsService"    class="com.atlanticds.server.Authentication.MongoUserDetailsService">
          </beans:bean>
      
          
           <beans:bean id="daoAuthenticationProvider"    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
              <beans:property name="userDetailsService" ref="mongoUserDetailsService" />
                <beans:property name="passwordEncoder" ref="encoder" />
          </beans:bean>
      web.xml is unchanged.

      Additional Spring dependencies in my maven pom:

      Code:
      <properties>
              <gwtVersion>2.7.0</gwtVersion>  
              <org.springframework-version>4.2.3.RELEASE</org.springframework-version>
              <org.springframework.security-version>4.0.3.RELEASE</org.springframework.security-version>
          </properties>
      <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-beans</artifactId>
                  <version>${org.springframework-version}</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-aop</artifactId>
                  <version>${org.springframework-version}</version>
              </dependency>
              
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-context</artifactId>
                  <version>${org.springframework-version}</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-core</artifactId>
                  <version>${org.springframework-version}</version>
              </dependency>
      
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-web</artifactId>
                  <version>${org.springframework-version}</version>
              </dependency>
              
              <dependency>
                  <groupId>org.springframework.security</groupId>
                  <artifactId>spring-security-core</artifactId>      
                  <version>${org.springframework.security-version}</version>
              </dependency>
              
              
              <dependency>
                  <groupId>org.springframework.security</groupId>
                  <artifactId>spring-security-web</artifactId>
                  <version>${org.springframework.security-version}</version>
              </dependency>
              
              <dependency>
                  <groupId>org.springframework.security</groupId>
                  <artifactId>spring-security-config</artifactId>
                  <version>${org.springframework.security-version}</version>
              </dependency>


      Comment


        #4
        Thanks for posting this! That change of the username/password parameter is enough to confuse people trying to apply the Spring 3 solution via copy-and-paste, this should help them past it.

        Comment

        Working...
        X