andy
andy

Reputation: 2993

Two concurrent authentications, managed separately, with Spring Security 3.1?

I am building an app that has two types of users:

How can I go about allowing someone to login/logout as a user and an administrator separately?

I have two realms defined using two http elements (I have two realms to allow separate login pages and user databases):

<security:http pattern="/admin/**" authentication-manager-ref="adminAuthManager"
    entry-point-ref="adminLoginUrlAuthEntryPoint" use-expressions="true">
    <security:intercept-url pattern="/admin/**" access="hasRole('admin')" />
    <security:access-denied-handler error-page="/admin/login" />
    <security:logout logout-url="/admin/logout" logout-success-url="/" />
    ...
</security:http>
<security:http pattern="/**" authentication-manager-ref="userAuthManager"
    entry-point-ref="userLoginUrlAuthEntryPoint" use-expressions="true">
    <security:intercept-url pattern="/**" access="permitAll" />
    <security:intercept-url pattern="/settings" access="hasRole('user')" />
    <security:access-denied-handler error-page="/login" />
    <security:logout logout-url="/logout" logout-success-url="/" />
    ...
</security:http>

With the current setup, I'm not able to allow a single session to be both an authenticated user and an authenticated administrator. When someone logs in as a user while logged in as an administrator, his/her administrator authentication is lost (or replaced) and vice versa.

I've thought about separating the two realms into two different webapps but would prefer not to, if possible.

EDIT: Here's an example of how I would like this to work:

  1. Person navigates to the site, let's say at path / which is open to all users
  2. Person clicks on login and authenticates at /login; person now has role "user"
  3. Person decides to navigate to a /admin/* page and is presented with the /admin/login page
  4. Person authenticates using another set of credentials at /admin/login; person now has roles "admin" AND "user"
  5. From the server point of view, when user is on an /admin/** page, the user's principal is the username he used for /admin/login; when on a /** page, the user's principal is the username he used for /login
  6. Person finishes admin activities and decides to log out of his admin session at /admin/logout; person loses "admin" role but is left with "user" role
  7. Person finally decides to log out of user role as well and goes to path /logout; person is now anonymous

I'm hoping this can be achieved without writing too much custom functionality.

Upvotes: 1

Views: 560

Answers (1)

Vlad Lositsky
Vlad Lositsky

Reputation: 36

I don't understand why you would want the same person to have two sets of credentials? This scenario is typically implemented using step-up authentication i.e. the user is always the same but he is prompted to re-authenticate when trying to access an admin area of the app. For example you may prompt him to enter some additional information or authenticate using a two factor token.

In the past I have implemented this using a custom AccessDecisionManager/Voter which checks if the user is trying to access a "more secure" area of the site and then throws an InsufficientAuthenticationException if he does not have the correct role. The entry point then handles this exception and prompts the user to re-authenticate and spring assigns the new roles

Upvotes: 2

Related Questions