Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: login by code

  1. #1
    Join Date
    Nov 2004
    Posts
    9

    Default login by code

    Hi,

    I am attempting to perform login and logout programmatically, the following twp routines seems to be working:

    Code:
    public class SecurityService {
    
        private final AuthenticationManager mAuthManager;
    
        public int login(String username, String password, String remoteAddr, HttpSession session) {
            if (session != null) {
                session.removeAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY);
                session.removeAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY);
            }
            AuthenticationException authEx;
            try {
                UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(username, password);
                upat.setDetails(remoteAddr);
                Authentication auth = mAuthManager.authenticate(upat);
                if (session != null)
                    session.setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY, auth);
                Context c = ContextHolder.getContext();
                if (c instanceof SecureContext) ((SecureContext)c).setAuthentication(auth);
                return LOGIN_SUCCESS;
            }
            catch (AuthenticationException e) {
            log.info("Authentication request failed: " + e);
            if (session != null)
                session.setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, authEx);
                return -1;
            }
        }
    
        public void logout(HttpSession session) {
            if (session != null) session.invalidate();
            Context c = ContextHolder.getContext();
            if (c instanceof SecureContext) ((SecureContext)c).setAuthentication(null);
        }
    
    }
    Can any guru glance it over for any potential problem ? thanx.

    -cs

  2. #2
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    You don't need to work with the HttpSession at all - only ContextHolder.

    The HttpSession will be refreshed automatically via the HttpSessionIntegrationFilter. Do a search in the forums or read its JavaDocs or the reference guide for more details.

  3. #3
    Join Date
    Nov 2004
    Posts
    9

    Default

    Quote Originally Posted by Ben Alex
    You don't need to work with the HttpSession at all - only ContextHolder.

    The HttpSession will be refreshed automatically via the HttpSessionIntegrationFilter. Do a search in the forums or read its JavaDocs or the reference guide for more details.
    Does this means for the login, I would do this (without the session handling code):

    Code:
                Authentication auth = mAuthManager.authenticate(upat);
                Context c = ContextHolder.getContext();
                if (c instanceof SecureContext) ((SecureContext)c).setAuthentication(auth);
    What happens if Context c is null, or not a SecureContext ? Or is it that Context c will always be present and an instanceof SecureContext ? Or I should do a ContextHolder.setContext() instead ?

    Thanx.

    -cs

  4. #4
    Join Date
    Nov 2004
    Posts
    9

    Default

    Unable to login after removing the session.setAttribute() code... hmm...

    Does the interceptor copies auth from session to context or from context to session ?

    -cs

  5. #5
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    Last edited by robyn; May 19th, 2006 at 05:05 AM.

  6. #6

    Default

    Hey,

    i just tried the programmatic authentication. Im using DAO based authentication with the MD5 password encoder. After registration the user gets a email with a verification ticket. Then klicking on the link with the ticket, the enrollment completes and the user gets logged in.

    It basically works, but there is a problem with the encoded password. After I do a login programmatically like this:

    Code:
    	private void login(User user, HttpServletRequest request) {
    		UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getPassword());
    
    		auth.setAuthenticated(true);
    		auth.setDetails(request.getRemoteAddr());
    		auth.setAuthorities(user.getAuthorities());
    
    		Context c = ContextHolder.getContext();
                if (c instanceof SecureContext) ((SecureContext)c).setAuthentication(auth);
    
    	}
    The authentication works till the next request. Then i get a worng password error and the login dialog pops up. DaoAuthenticationProvider seems to encode the password _again_ and then check against the already encoded password.

    The problem is that i don't know the plain password at this stage.

    Any quick hints how to get around this?

    The only solution I see now is writing my own DaoAuthenticationProvider that can detect wether a password is encoded or not and act accordingly (use password encoder or not). I don't like to use plain passwords in the database at all.

    Ideas?

    l8er
    -andi

    PS: I suspect the same problem would occur if I (optionally) encode the password on the client side (via javascript) and send the encoded password over the net.

  7. #7
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    Quote Originally Posted by thyrell
    PS: I suspect the same problem would occur if I (optionally) encode the password on the client side (via javascript) and send the encoded password over the net.
    Would that defeat the whole purpose of encoding in the first place? Because a hacked database could then be used to send a HTTP request containing the hashed code as it was stored in the database. No knowledge of the cleartext password would ever be needed.

    Back to your enrollment question, I think your easiest solution is for your MVC controller that validates the signup ticket should place a unique Authentication instance on the ContextHolder, say an AutomatedSignInAuthenticationToken. There would be a corresponding AutomatedSignInAuthenticationProvider which can recognise the token and treat it as valid, populating the GrantedAuthority[]s and user details from the same AuthenticationDao as was used by DaoAuthenticationProvider for normal, interactive authentication attempts. The benefit of this model is your AutomatedSignInAuthenticationToken can extend from say RememberMeAuthenticationToken, which the net.sf.acegisecurity.AuthenticationTrustResolverIm pl will immediately recognise as being some sort of of remember-me-like token. This can be helpful if you wish your AccessDecisionManager to throw an InsufficientAuthenticationException for certain high-security operations (instead of a standard AccessDeniedException).

  8. #8

    Default

    Hi Ben,

    thanks for your kind help.

    >> MD5 clientside >>
    Would that defeat the whole purpose of encoding in the first place?
    Of course, you are absolutely right about this. Makes nullifies encoding in the database. Sometimes I don't think before i write

    Ok, so you suggest using the remember-me support, basically? But do I need to create the extra provider? In my EnrollmentController the User object (implements UserDetails) is already loaded. So what I need is that I can put my principal on the context, marked as authenticated and that's it.

    Can't I just put a RememberMeToken on the context and set-up the remember me services like described in the docs?:

    Code:
    private void login(User user, HttpServletRequest request) { 
          RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken("springRocks", user, user.getAuthorities()); 
    
          auth.setAuthenticated(true); 
    
          Context c = ContextHolder.getContext(); 
                if (c instanceof SecureContext) ((SecureContext)c).setAuthentication(auth); 
    
       }
    Code:
    <bean id="rememberMeProcessingFilter" class="net.sf.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
      <property name="rememberMeServices"><ref local="rememberMeServices"/></property>
    </bean>
    
    <bean id="rememberMeServices" class="net.sf.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
      <property name="authenticationDao"><ref local="myDao"/></property>
      <property name="key"><value>springRocks</value></property>
    </bean>
       
    <bean id="rememberMeAuthenticationProvider" class="net.sf.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
      <property name="key"><value>springRocks</value></property>
    </bean>
    I'm suprised that nobody had that problem before. This auto-sign in after password-change (or verified enrollment( adds much to user-friendlyness of a site.


    -andi

  9. #9
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    Quote Originally Posted by thyrell
    Can't I just put a RememberMeToken on the context and set-up the remember me services like described in the docs?
    Indeed you can. That sounds a lot simpler to me than writing another provider.

  10. #10

    Default

    Hi Ben,

    ... and it works perfectly fine Thanks a lot for lining it out.

    -andi

Similar Threads

  1. Replies: 13
    Last Post: Oct 24th, 2007, 10:55 AM
  2. Replies: 4
    Last Post: Jun 20th, 2007, 11:06 AM
  3. EHCaching Hibernate
    By dencamel in forum Data
    Replies: 3
    Last Post: Sep 6th, 2005, 09:03 PM
  4. Acegi - Login Tapestry
    By john017 in forum Security
    Replies: 1
    Last Post: Feb 4th, 2005, 01:11 AM
  5. Please help! Unit testing code for JPetStore
    By lakershen in forum Container
    Replies: 4
    Last Post: Jan 13th, 2005, 05:00 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •