<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>
  Authentication buildRunAs(Authentication authentication, Object object, 
      List&lt;ConfigAttribute&gt; 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>
<![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>
