12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- <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<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>
- <![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>
|