You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
3.7 KiB
61 lines
3.7 KiB
[[runas]] |
|
= Run-As Authentication Replacement |
|
|
|
[[runas-overview]] |
|
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` indicates 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 can call other objects that require different authentication and authorization credentials. |
|
It can also 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. |
|
|
|
[[runas-config]] |
|
== Configuration |
|
Spring Security provides a `RunAsManager` interface: |
|
|
|
[source,java] |
|
---- |
|
Authentication buildRunAs(Authentication authentication, Object object, |
|
List<ConfigAttribute> 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 that the configured `RunAsManager` supports the type of secure object that the security interceptor presents. |
|
|
|
Spring Security provides one concrete implementation of `RunAsManager`. |
|
The `RunAsManagerImpl` class returns a replacement `RunAsUserToken` if any `ConfigAttribute` starts with `RUN_AS_`. |
|
If any such `ConfigAttribute` is found, the replacement `RunAsUserToken` contains the same principal, credentials, and granted authorities as the original `Authentication` object, along with a new `SimpleGrantedAuthority` for each `RUN_AS_` `ConfigAttribute`. |
|
Each new `SimpleGrantedAuthority` is prefixed with `ROLE_`, followed by the `RUN_AS` `ConfigAttribute`. |
|
For example, a `RUN_AS_SERVER` results in the replacement `RunAsUserToken` containing a `ROLE_RUN_AS_SERVER` granted authority. |
|
|
|
The replacement `RunAsUserToken` is like any other `Authentication` object. |
|
It needs to be authenticated by the `AuthenticationManager`, probably through delegation to a suitable `AuthenticationProvider`. |
|
The `RunAsImplAuthenticationProvider` performs such authentication. |
|
It 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: |
|
|
|
[source,xml] |
|
---- |
|
<bean id="runAsManager" |
|
class="org.springframework.security.access.intercept.RunAsManagerImpl"> |
|
<property name="key" value="my_run_as_password"/> |
|
</bean> |
|
|
|
<bean id="runAsAuthenticationProvider" |
|
class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> |
|
<property name="key" value="my_run_as_password"/> |
|
</bean> |
|
---- |
|
|
|
By using the same key, each `RunAsUserToken` can be validated because it was created by an approved `RunAsManagerImpl`. |
|
The `RunAsUserToken` is immutable after creation, for security reasons.
|
|
|