98 lines
5.9 KiB
XML
98 lines
5.9 KiB
XML
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="runas">
|
|
<info>
|
|
<title>Run-As Authentication Replacement</title>
|
|
</info>
|
|
|
|
<section xml:id="runas-overview">
|
|
<info>
|
|
<title>Overview</title>
|
|
</info>
|
|
|
|
<para>The <classname>AbstractSecurityInterceptor</classname> is able to temporarily replace
|
|
the <interfacename>Authentication</interfacename> object in the
|
|
<interfacename>SecurityContext</interfacename> and
|
|
<classname>SecurityContextHolder</classname> during the secure object callback phase.
|
|
This only occurs if the original <interfacename>Authentication</interfacename> object
|
|
was successfully processed by the <interfacename>AuthenticationManager</interfacename>
|
|
and <interfacename>AccessDecisionManager</interfacename>. The
|
|
<literal>RunAsManager</literal> will indicate the replacement
|
|
<interfacename>Authentication</interfacename> object, if any, that should be used during
|
|
the <literal>SecurityInterceptorCallback</literal>.</para>
|
|
|
|
<para>By temporarily replacing the <interfacename>Authentication</interfacename> 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
|
|
<interfacename>GrantedAuthority</interfacename> objects. Because Spring Security
|
|
provides a number of helper classes that automatically configure remoting protocols
|
|
based on the contents of the <classname>SecurityContextHolder</classname>, these run-as
|
|
replacements are particularly useful when calling remote web services</para>
|
|
</section>
|
|
|
|
<section xml:id="runas-config">
|
|
<info>
|
|
<title>Configuration</title>
|
|
</info>
|
|
<para>A <literal>RunAsManager</literal> interface is provided by Spring Security:
|
|
<programlisting language="java">
|
|
Authentication buildRunAs(Authentication authentication, Object object,
|
|
List<ConfigAttribute> config);
|
|
boolean supports(ConfigAttribute attribute);
|
|
boolean supports(Class clazz);
|
|
</programlisting> </para>
|
|
|
|
<para>The first method returns the <interfacename>Authentication</interfacename> object that
|
|
should replace the existing <interfacename>Authentication</interfacename> object for the
|
|
duration of the method invocation. If the method returns <literal>null</literal>, it
|
|
indicates no replacement should be made. The second method is used by the
|
|
<classname>AbstractSecurityInterceptor</classname> as part of its startup validation of
|
|
configuration attributes. The <literal>supports(Class)</literal> method is called by a
|
|
security interceptor implementation to ensure the configured
|
|
<literal>RunAsManager</literal> supports the type of secure object that the security
|
|
interceptor will present.</para>
|
|
|
|
<para>One concrete implementation of a <literal>RunAsManager</literal> is provided with
|
|
Spring Security. The <literal>RunAsManagerImpl</literal> class returns a replacement
|
|
<literal>RunAsUserToken</literal> if any <literal>ConfigAttribute</literal> starts with
|
|
<literal>RUN_AS_</literal>. If any such <literal>ConfigAttribute</literal> is found, the
|
|
replacement <literal>RunAsUserToken</literal> will contain the same principal,
|
|
credentials and granted authorities as the original
|
|
<interfacename>Authentication</interfacename> object, along with a new
|
|
<literal>GrantedAuthorityImpl</literal> for each <literal>RUN_AS_</literal>
|
|
<literal>ConfigAttribute</literal>. Each new <literal>GrantedAuthorityImpl</literal>
|
|
will be prefixed with <literal>ROLE_</literal>, followed by the
|
|
<literal>RUN_AS</literal> <literal>ConfigAttribute</literal>. For example, a
|
|
<literal>RUN_AS_SERVER</literal> will result in the replacement
|
|
<literal>RunAsUserToken</literal> containing a <literal>ROLE_RUN_AS_SERVER</literal>
|
|
granted authority.</para>
|
|
|
|
<para>The replacement <literal>RunAsUserToken</literal> is just like any other
|
|
<interfacename>Authentication</interfacename> object. It needs to be authenticated by
|
|
the <interfacename>AuthenticationManager</interfacename>, probably via delegation to a
|
|
suitable <classname>AuthenticationProvider</classname>. The
|
|
<literal>RunAsImplAuthenticationProvider</literal> performs such authentication. It
|
|
simply accepts as valid any <literal>RunAsUserToken</literal> presented.</para>
|
|
|
|
<para>To ensure malicious code does not create a <literal>RunAsUserToken</literal> and
|
|
present it for guaranteed acceptance by the
|
|
<literal>RunAsImplAuthenticationProvider</literal>, the hash of a key is stored in all
|
|
generated tokens. The <literal>RunAsManagerImpl</literal> and
|
|
<literal>RunAsImplAuthenticationProvider</literal> is created in the bean context with
|
|
the same key: <programlisting language="xml">
|
|
<![CDATA[
|
|
<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>]]></programlisting></para>
|
|
<para>By using the same key, each <literal>RunAsUserToken</literal> can be validated it was
|
|
created by an approved <literal>RunAsManagerImpl</literal>. The
|
|
<literal>RunAsUserToken</literal> is immutable after creation for security
|
|
reasons</para>
|
|
</section>
|
|
</chapter>
|