Announcement Announcement Module
Collapse
No announcement yet.
Authentication only once per session Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Authentication only once per session

    Hi all,

    I'm currently using a JAAS LoginModule to authenticate users and in the process of integrating it, I uncovered a little bit more of my ignorance (I hate it when that happens). I was under the impression that an Authentication object is validated with an AuthenticationManager once, but it seems that it is validated on every request. I stumbled across this by watching some debug output and then found the documentation that describes this as normal behaviour in the reference guide.

    The trick is, the JAAS authentication I do is quite heavyweight and relies on single use passwords, so having every request be authenticated is unwieldly. It would seem to me that maybe I have a config error though as Acegi seems to have a concept of a "Authenticated" authentication, but what I am seeing is that that it "re-authenticates" the Authentication object in the SecureContext on every web request handled.

    I seem to get one of these on each web request. And this is what I am basing this observation on.

    2005-03-28 22:47:14,172 DEBUG [net.sf.acegisecurity.intercept.AbstractSecurityInt erceptor] - <Secure object: FilterInvocation: URL: /AuthWeb/checkBalance.doWeb; ConfigAttributes: [ROLE_WEB_USER]>
    2005-03-28 22:47:14,172 DEBUG [net.sf.acegisecurity.providers.ProviderManager] - <Authentication attempt using net.sf.acegisecurity.providers.dao.DaoAuthenticati onProvider>
    making a call to the DB for authentication
    2005-03-28 22:47:14,217 DEBUG [net.sf.acegisecurity.intercept.AbstractSecurityInt erceptor] - <Authenticated: net.sf.acegisecurity.providers.UsernamePasswordAut henticationToken@1920208: Username: User@a4420a01; Password: [PROTECTED]; Authenticated: true; Details: net.sf.acegisecurity.ui.WebAuthenticationDetails@b 7dc78: RemoteIpAddress: 127.0.0.1; SessionId: 49C207070037F80F329CCEEE6B0A1343; Granted Authorities: ROLE_SERVICE_USER, ROLE_WEB_USER, ROLE_USER>
    2005-03-28 22:47:14,217 DEBUG [net.sf.acegisecurity.intercept.AbstractSecurityInt erceptor] - <Authorization successful>
    Is my configuration doing strange things, or is this really normal behaviour? If it is normal behaviour then is there a way to only authenticate once per session?

    Thanks in advance,
    Deakin.

  • #2
    Every time a users credentials are presented (especially basic auth, where they are presented on every request for example), they will be presented to the AuthenticationManager. The AuthenticationManager will then proceed to present them to all of the AuthenticationProviders.

    I see in your log you are using the DaoAuthenticationProvider. If you have the DaoAuthenticationProvider configured with a NullUserCache, it will never cache the authentication object. What the DaoAuthenticationProvider does internally is compare the authentication object with the cache, if it is not cached, then authenticate() it. If it is cached (and the password in the cache matches the password presented in the authentication object) then do not re-authenticate it.

    Long story short, if you are using the NullUserCache the DaoAuthenticationProvider will have no choice but to re-authenticate the authentication object.

    You mentioned Jaas though, so I'm unclear where Jaas fits into this. Are you using the JaasAuthenticationProvider? If so, it isn't as smart as the DaoAuthenticationProvider, it doesn't cache the authentication. It leaves the re-authentication issue up to the configured LoginModules.

    Comment


    • #3
      Thanks for your reply,

      Yep, that's what I thought. There is alwasys a handoff to the AuthenticationManager for authentication. I had a look at the code for AbstractSecurityInterceptor and found it in there. I considered the cache but I noticed that it wouldn't work for JAAS, and that is really what I am targeting.

      Ok, so to work around this I am going to do the following. (I hope this helps others):

      I will give up on the JAAS provider and instead write a seperate provider for the authentication mechanism I am trying to use. I will then create a custom Authentication and have my provider authenticate the custom Authentication. This custom Authentication will have a "validated" field in it which will be set to "true" on the first valid authentication. The provider will consider the "validated" field whenever it is asked to authenticate the Authentication. If it is set to true, it will not do any processing, simply return the already validated Authentication.

      This seems like it will get me around it. My question is, why validate authentication on every request? Why does the AbstractSecurityInterceptor always try to authenticate the Authentication object? It seems that this behaviour limits what kind of authentication you can do. Simple, non-user-interactive stuff will work, but anything else can't be used without a workaround as specified above.

      Cheers,
      Deakin

      Comment


      • #4
        Originally posted by Deakin
        My question is, why validate authentication on every request? Why does the AbstractSecurityInterceptor always try to authenticate the Authentication object? It seems that this behaviour limits what kind of authentication you can do. Simple, non-user-interactive stuff will work, but anything else can't be used without a workaround as specified above.
        We validate on every request as it provides the most flexible way of implementing authentication logic. If we don't validate on every request, we're forced to store authentication state somewhere. Whilst we do as a convenience in the case of webapps using form authentication, we equally leverage the browser to store it in the case of BASIC and Digest authentication (ie HttpSession is optional). Recall that AuthenticationManagers (well, more commonly AuthenticationProviders in practice) are free to store authentication state internally. Many actually do that, such as the CAS provider. It returns a token that indicates "I've already processed this principal, and here's a token that proves it, so just re-present that next time around and I won't bother re-authenticating from scratch".

        The nice thing about this strategy, aside from flexibility and avoiding mandatory session state, is that it also gives an excellent hook to cancel an authentication at any time. This is helpful if accounts suddenly get cancelled (eg someone is terminated) or there is a change in their GrantedAuthority[]s (eg someone gets a new role added) or the UserDetails stored in Authentication changes (eg someone updates their surname following marriage). As I said before, flexiblity is why we do it this way. With caching subsystems and re-presentable tokens, it's not really a major design trade-off.

        HTH.

        Comment

        Working...
        X