The AbstractSecurityInterceptor
is able to
temporarily replace the Authentication
object in
the SecurityContext
and
SecurityContextHolder
during the secure object
callback phase. This only occurs if the original
Authentication
object was successfully processed by
the AuthenticationManager
and
AccessDecisionManager
. The
RunAsManager
will indicate the replacement
Authentication
object, if any, that should be used
during the SecurityInterceptorCallback
.
By temporarily replacing the Authentication
object during the secure object callback phase, the secured invocation
will be able to call other objects which require different
authentication and authorization credentials. It will also be able to
perform any internal security checks for specific
GrantedAuthority
objects. Because Spring Security
provides a number of helper classes that automatically configure
remoting protocols based on the contents of the
SecurityContextHolder
, these run-as replacements
are particularly useful when calling remote web services
A RunAsManager
interface is provided by Spring Security:
Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config); boolean supports(ConfigAttribute attribute); boolean supports(Class clazz);
The first method returns the Authentication
object that should replace the existing
Authentication
object for the duration of the
method invocation. If the method returns null
, it
indicates no replacement should be made. The second method is used by
the AbstractSecurityInterceptor
as part of its
startup validation of configuration attributes. The
supports(Class)
method is called by a security
interceptor implementation to ensure the configured
RunAsManager
supports the type of secure object
that the security interceptor will present.
One concrete implementation of a RunAsManager
is provided with Spring Security. The
RunAsManagerImpl
class returns a replacement
RunAsUserToken
if any
ConfigAttribute
starts with
RUN_AS_
. If any such
ConfigAttribute
is found, the replacement
RunAsUserToken
will contain the same principal,
credentials and granted authorities as the original
Authentication
object, along with a new
GrantedAuthorityImpl
for each
RUN_AS_
ConfigAttribute
. Each
new GrantedAuthorityImpl
will be prefixed with
ROLE_
, followed by the RUN_AS
ConfigAttribute
. For example, a
RUN_AS_SERVER
will result in the replacement
RunAsUserToken
containing a
ROLE_RUN_AS_SERVER
granted authority.
The replacement RunAsUserToken
is just like
any other Authentication
object. It needs to be
authenticated by the AuthenticationManager
,
probably via delegation to a suitable
AuthenticationProvider
. The
RunAsImplAuthenticationProvider
performs such
authentication. It simply accepts as valid any
RunAsUserToken
presented.
To ensure malicious code does not create a
RunAsUserToken
and present it for guaranteed
acceptance by the RunAsImplAuthenticationProvider
,
the hash of a key is stored in all generated tokens. The
RunAsManagerImpl
and
RunAsImplAuthenticationProvider
is created in the
bean context with the same key:
<bean id="runAsManager" class="org.springframework.security.runas.RunAsManagerImpl"> <property name="key" value="my_run_as_password"/> </bean> <bean id="runAsAuthenticationProvider" class="org.springframework.security.runas.RunAsImplAuthenticationProvider"> <property name="key" value="my_run_as_password"/> </bean>
By using the same key, each RunAsUserToken
can be validated it was created by an approved
RunAsManagerImpl
. The
RunAsUserToken
is immutable after creation for
security reasons