<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="secure-object-impls"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <info>
    <title>Secure Object Implementations</title>
  </info>
  <section xml:id="aop-alliance">
    <info>
      <title>AOP Alliance (MethodInvocation) Security Interceptor</title>
    </info>
    <para> Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s needed
      quite a lot of boiler plate configuration. Now the recommended approach for method security is
      to use <link xlink:href="#ns-method-security">namespace configuration</link>. This way the
      method security infrastructure beans are configured automatically for you so you don't really
      need to know about the implementation classes. We'll just provide a quick overview of the
      classes that are involved here. </para>
    <para> Method security in enforced using a <classname>MethodSecurityInterceptor</classname>,
      which secures <classname>MethodInvocation</classname>s. Depending on the configuration
      approach, an interceptor may be specific to a single bean or shared between multiple beans.
      The interceptor uses a <interfacename>MethodDefinitionSource</interfacename> instance to
      obtain the configuration attributes that apply to a particular method invocation.
        <classname>MapBasedMethodDefinitionSource</classname> is used to store configuration
      attributes keyed by method names (which can be wildcarded) and will be used internally when
      the attributes are defined in the application context using the
        <literal>&lt;intercept-methods&gt;</literal> or <literal>&lt;protect-point&gt;</literal>
      elements. Other implementations will be used to handle annotation-based configuration. </para>
    <section>
      <title>Explicit MethodSecurityIterceptor Configuration</title>
      <para> You can of course configure a <classname>MethodSecurityIterceptor</classname> directly
        in your application context for use with one of Spring AOP's proxying mechanisms: <programlisting><![CDATA[
<bean id="bankManagerSecurity"
    class="org.springframework.security.intercept.aopalliance.MethodSecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="accessDecisionManager" ref="accessDecisionManager"/>
  <property name="afterInvocationManager" ref="afterInvocationManager"/>
  <property name="securityMetadataSource">
    <value>
      com.mycompany.BankManager.delete*=ROLE_SUPERVISOR
      com.mycompany.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR
    </value>
  </property>
</bean> ]]>
</programlisting></para>
    </section>
  </section>
  <section xml:id="aspectj">
    <info>
      <title>AspectJ (JoinPoint) Security Interceptor</title>
    </info>
    <para>The AspectJ security interceptor is very similar to the AOP Alliance security interceptor
      discussed in the previous section. Indeed we will only discuss the differences in this
      section.</para>
    <para>The AspectJ interceptor is named <literal>AspectJSecurityInterceptor</literal>. Unlike the
      AOP Alliance security interceptor, which relies on the Spring application context to weave in
      the security interceptor via proxying, the <literal>AspectJSecurityInterceptor</literal> is
      weaved in via the AspectJ compiler. It would not be uncommon to use both types of security
      interceptors in the same application, with <literal>AspectJSecurityInterceptor</literal> being
      used for domain object instance security and the AOP Alliance
        <classname>MethodSecurityInterceptor</classname> being used for services layer
      security.</para>
    <para>Let's first consider how the <literal>AspectJSecurityInterceptor</literal> is configured
      in the Spring application context:</para>
    <programlisting><![CDATA[
<bean id="bankManagerSecurity"
     class="org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="accessDecisionManager" ref="accessDecisionManager"/>
  <property name="afterInvocationManager" ref="afterInvocationManager"/>
  <property name="securityMetadataSource">
    <value>
        com.mycompany.BankManager.delete*=ROLE_SUPERVISOR
        com.mycompany.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR
    </value>
</property>
</bean>]]>        </programlisting>
    <para>As you can see, aside from the class name, the
        <literal>AspectJSecurityInterceptor</literal> is exactly the same as the AOP Alliance
      security interceptor. Indeed the two interceptors can share the same
        <literal>securityMetadataSource</literal>, as the
        <interfacename>SecurityMetadataSource</interfacename> works with
        <literal>java.lang.reflect.Method</literal>s rather than an AOP library-specific class. Of
      course, your access decisions have access to the relevant AOP library-specific invocation (ie
        <classname>MethodInvocation</classname> or <literal>JoinPoint</literal>) and as such can
      consider a range of addition criteria when making access decisions (such as method
      arguments).</para>
    <para>Next you'll need to define an AspectJ <literal>aspect</literal>. For example:</para>
    <programlisting language="java">
package org.springframework.security.samples.aspectj;

import org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor;
import org.springframework.security.intercept.aspectj.AspectJCallback;
import org.springframework.beans.factory.InitializingBean;

public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {

private AspectJSecurityInterceptor securityInterceptor;

pointcut domainObjectInstanceExecution(): target(PersistableEntity)
     &amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);

Object around(): domainObjectInstanceExecution() {
  if (this.securityInterceptor == null) {
    return proceed();
  }

  AspectJCallback callback = new AspectJCallback() {
      public Object proceedWithObject() {
        return proceed();
      }
  };

  return this.securityInterceptor.invoke(thisJoinPoint, callback);
}

public AspectJSecurityInterceptor getSecurityInterceptor() {
  return securityInterceptor;
}

public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
  this.securityInterceptor = securityInterceptor;
}

public void afterPropertiesSet() throws Exception {
  if (this.securityInterceptor == null)
    throw new IllegalArgumentException("securityInterceptor required");
  }
}</programlisting>
    <para>In the above example, the security interceptor will be applied to every instance of
        <literal>PersistableEntity</literal>, which is an abstract class not shown (you can use any
      other class or <literal>pointcut</literal> expression you like). For those curious,
        <literal>AspectJCallback</literal> is needed because the <literal>proceed();</literal>
      statement has special meaning only within an <literal>around()</literal> body. The
        <literal>AspectJSecurityInterceptor</literal> calls this anonymous
        <literal>AspectJCallback</literal> class when it wants the target object to continue.</para>
    <para>You will need to configure Spring to load the aspect and wire it with the
        <literal>AspectJSecurityInterceptor</literal>. A bean declaration which achieves this is
      shown below:</para>
    <programlisting><![CDATA[
<bean id="domainObjectInstanceSecurityAspect"
   class="org.springframework.security.samples.aspectj.DomainObjectInstanceSecurityAspect"
   factory-method="aspectOf">
  <property name="securityInterceptor" ref="aspectJSecurityInterceptor"/>
</bean>]]>
    </programlisting>
    <para>That's it! Now you can create your beans from anywhere within your application, using
      whatever means you think fit (eg <literal>new Person();</literal>) and they will have the
      security interceptor applied.</para>
  </section>
</chapter>
