Home | Contents | Latest | Previous | Next

Session Limitation with Acegi

From: "andrew cooke" <andrew@...>

Date: Mon, 27 Feb 2006 14:44:16 -0300 (CLST)

Sometimes it's useful to restrict a user a single session.  This
simplifies the logic needed to guarantee certain restrictions.

For example, I always want a user to have a minimum of one valid email
address.  With two parallel sessions and two valid emails a user could
delete one email in each session and I would need to verify consistency in
the database.  Restrictig to one session lets me implement the restriction
in the business logic.

However, the exact configuration was not obvious.  After some
experimentation the following seemed to work.

First, you need some way of detectig when sessions expire.  This is
largely automatic as long as you register the following in web.xml:

  <!-- used to track session events (single user session) -->
  <listener>
    <listener-class>org.acegisecurity.ui.\
      session.HttpSessionEventPublisher</listener-class>
  </listener>

I have all my authentication-related xml in web-authentication.xml (and
referenced via context-param in web.xml).  It includes:

  <bean id="authenticationManager"
    class="org.acegisecurity.providers.ProviderManager">
    <property name="sessionController" ref="singleSession"/>
    <property name="providers">
      ...
    </property>
  </bean>

  <bean id="sessionRegistry"
    class="org.acegisecurity.concurrent.SessionRegistryImpl"/>

  <bean id="singleSession"
    class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
    <property name="maximumSessions" value="1"/>
    <property name="exceptionIfMaximumExceeded" value="true"/>
    <property name="sessionRegistry" ref="sessionRegistry"/>
  </bean>

Which is all that is needed (I suspect sessionRegistry is supplied by
default anyway).

The way it seems to work is as follows:
- authenticationManager calls the appropriate provider
- if that succeeds, it calls sessionController
- sessionController applies the appropriate logic, using the information
  in sessionRegistry
- sessionRegistry is correct because of the event system (which includes
  the listener you registered).

Andrew

Comment on this post