Announcement Announcement Module
Collapse
No announcement yet.
Automatic login after user registration Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Automatic login after user registration

    Hi, I have an existing struts action that sticks a row in my users table and then does a redirect (yikes, passwords on a GET = bad) to j_security_check. That seemed at the time the only way to have login after registration on Tomcat without having the user enter their information again.

    Now I have migrated to Acegi, and wow, everything works great, except I am not a strong Spring user, so doing anything that is not well documented is going to have a learning curve.

    That said, is there any best practive in Acegi out there to authenticate a user from inside a struts action? I have found some examples, but I can't seem to find the underlying classes (SecureContext, the Manager that you call doAuthentication() on, etc.) This has to be something that most people do, so what's the simple way to do it?

    Here is an example that I found but couldn't fully understand.

    http://forum.springframework.org/showthread.php?t=15417

    Thanks!

  • #2
    OK, I got this working. I was a little confused about how to access beans declared in my securityContext.xml, but I found out and here goes:

    Code:
    SecurityContext context = SecurityContextHolder.getContext();
    try{
      GrantedAuthority[] grantedAuthorities = new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_user")};
    
      UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password, grantedAuthorities);
      authentication.setDetails(request.getRemoteAddr());
    
      ProviderManager pm = (ProviderManager)WebApplicationContextUtils.getWebApplicationContext(getServletContext()).getBean("authenticationManager");
      pm.doAuthentication(authentication);
      context.setAuthentication(authentication);
    }catch(AuthenticationException e){
      context.setAuthentication(null);
      log.error("Login failed after registration. This should never happen: ", e);
    }catch(BeansException e){
      log.error("Could not get bean from web application context: ", e);
    }
    The important part is how you access the ProviderManager from outside the filter chain (ie, inside a struts action). This line resolves an Object from the context using the bean name and you just cast it to whatever type it should be.

    Code:
    ProviderManager pm = (ProviderManager)WebApplicationContextUtils.getWebApplicationContext(getServletContext()).getBean("authenticationManager");
    Remember, I am not checking credentials or anything here, so it is only performed after a successful registration using the same username and password that was used to register.

    Comment


    • #3
      If you don't actually need to perform an authentication after your registration process, the you can probably just set an Authentication object on the security context:

      SecurityContextHolder.getContext().setAuthenticati on(new UsernamePasswordAuthenticationToken("name", "password", authorities));

      Comment


      • #4
        I am not sure if anyone is still interested in this 2 year old thread, but you can grab the granted authorities from your user details service if you need to do that. In this case, the authenticationManager and the userDetailsService are both injected into the bean via Spring DI:

        Code:
            private ProviderManager authenticationManager;
            
            private JdbcDaoImpl userDetailsService;
        
            /**
             * Programatically authenticate the user
             */
            public void authenticate(String username, String password) {
                try {
                    UserDetails details = userDetailsService.loadUserByUsername(username);
                    UsernamePasswordAuthenticationToken usernameAndPassword = 
                        new UsernamePasswordAuthenticationToken(
                            username, password, details.getAuthorities());
        
                    // Authenticate, just to be sure
                    Authentication auth = authenticationManager.doAuthentication(usernameAndPassword);
        
                    // Place the new Authentication object in the security context.
                    SecurityContextHolder.getContext().setAuthentication(auth);
                    
                } catch (AuthenticationException e) {
                    SecurityContextHolder.getContext().setAuthentication(null);
                    log.error("Login failed after registration. This should never happen: ", e);
                }
            }
        
            public void setAuthenticationManager(ProviderManager authenticationManager) {
                this.authenticationManager = authenticationManager;
            }
        
            public void setuserDetailsService(JdbcDaoImpl userDetailsService) {
                this.userDetailsService = userDetailsService;
            }

        Comment


        • #5
          Autologin with PrincipalSpringSecurityUserToken

          The above solution was pretty good, after some minor changes it's worked fine.
          Thanks.

          Code:
          /**
           * Automatic login after successful registration.
           * @param username
           */
          public boolean autoLogin(String username) {
           try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            Authentication authentication = new PrincipalSpringSecurityUserToken(username,
              username, userDetails.getPassword(), userDetails.getAuthorities(), userDetails);
          
            // Place the new Authentication object in the security context.
            SecurityContextHolder.getContext().setAuthentication(authentication);
           }
           catch (Exception e) {
            SecurityContextHolder.getContext().setAuthentication(null);
            logger.error("Exception", e);
            return false;
           }
           return true;
          }

          Comment


          • #6
            Just to add my two pence worth, I prefer to handle the autoLogin using AuthenticationManager and UsernamePasswordAuthenticationToken. (The UserDetails look-up will happen in the authenticationManager, as in the 'normal' log in route).

            Code:
              @Resource
              private ProviderManager authenticationManager;
            
              public void autoLogin(HttpServletRequest request, HttpServletResponse response, String username, String password) {
                try {
                  // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated
                  UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
                  token.setDetails(new WebAuthenticationDetails(request));
                  Authentication authentication = authenticationManager.authenticate(token);
                  logger.debug("Logging in with {}", authentication.getPrincipal());
                  SecurityContextHolder.getContext().setAuthentication(authentication);
                } catch (Exception e) {
                  SecurityContextHolder.getContext().setAuthentication(null);
                  logger.error("Failure in autoLogin", e);
                }
              }
            Last edited by damien; May 19th, 2009, 10:50 AM.

            Comment


            • #7
              Originally posted by omg!ponies View Post
              The important part is how you access the ProviderManager from outside the filter chain (ie, inside a struts action).
              I don't see how this could work, as if you are accessing the SecurityContext outside of the filter chain, HttpSessionContextIntegrationFilter will not be able to update the SecurityContext at the end of the request. The next request will get whatever the SecurityContext was prior.

              Comment

              Working...
              X