Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

Switch Once - Stateless Impersonation

For testing APIs, there is a need to allow certain privileged users to impersonate other users. We already provide this feature in our web applications through Spring Security's "Switch User" filter.

The API apps are a little different from traditional web apps in that the security context is stateless - a user's authorization information is not preserved between requests. Spring's switch-user functionality assumes the traditional stateful setup, so out-of-the-box  does not support the stateless API model.

What we want to happen in a single request:

  • User requests resource, supplying their own credentials and the identity of the user they want to impersonate (target user).
  • If the authenticated user has authorization to do impersonation, Spring Security's user switch is invoked.
  • The target user's authorizations are applied to the resource request,  which would be allowed or denied.
  • The Spring Security "exit switch" is performed, reverting to the authenticated user
  • The response is delivered to the authenticated user

New Filter SwitchUserOnceFilter - Configuring A Web App

A new filter was created in csf-security to handle this functionality: edu.mit.csf.security.spring.filter.SwitchUserOnceFilter

For a web app to use this filter, it must be configured as a bean using this XML:

Code Block
	<bean id="switchUserOnceFilter" class="edu.mit.csf.security.spring.filter.SwitchUserOnceFilter">
		<property name="userDetailsService" ref="mitAuthorizationUserDetailService"/>
		<property name="targetUrl" value="/"/>
		<property name="switchUserRole" value="ESAPIS_IMPERSONATE" />
	</bean>

IMPORTANT: the switchUserRole property specifies the role that a user must have in order to perform impersonation. So any user who needs to do impersonation must have this role, and must authenticate to the API as themself.

The switchUserOnce filter should be configured into the Spring Security chain of filters BEFORE the filterSecurityInterceptor entry, e.g.:

Code Block
            <security:filter-chain pattern="/**" filters="esapisSecurityContextNonPersistenceFilter,
           		logoutFilter,
				hashAuthenticationProcessingFilter,
           		esapisAuthenticationProcessingFilter,
           		basicAuthenticationProcessingFilter,
           		exceptionTranslationFilter,
           		switchUserOnceFilter,
           		filterSecurityInterceptor"
            />

Placing the switchUserOnceFilter before the filterSecurityInterceptor ensures that filterSecurityInterceptor applies its authorization rules to the user we are impersonating, not the authenticated user.

Performing Impersonation

To actually do impersonation, the user must authenticate to the API application with their own credentials, whether this is via an X509 certificate or Touchstone login. The user must also supply a special request header that specifies the kerberos name of the user they want to impersonate. This header is:

X-Switch-User-Once

and as a request header, would look like this (impersonating David):

X-Switch-User-Once: dtanner

For reference, this header name is a static field in the filter: SwitchUserOnceFilter.SWITCH_USER_ONCE_HEADER