|  | @@ -7,7 +7,7 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      <subtitle>Reference Documentation</subtitle>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    <releaseinfo>0.6.1</releaseinfo>
 | 
	
		
			
				|  |  | +    <releaseinfo>0.7</releaseinfo>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      <authorgroup>
 | 
	
		
			
				|  |  |        <author>
 | 
	
	
		
			
				|  | @@ -202,8 +202,8 @@
 | 
	
		
			
				|  |  |          directly. For example, it would be possible to build a new secure
 | 
	
		
			
				|  |  |          object to secure calls to a messaging system that does not use
 | 
	
		
			
				|  |  |          <literal>MethodInvocation</literal>s. Most Spring applications will
 | 
	
		
			
				|  |  | -        simply use the two currently supported secure object types
 | 
	
		
			
				|  |  | -        (<literal>MethodInvocation</literal> and
 | 
	
		
			
				|  |  | +        simply use the three currently supported secure object types
 | 
	
		
			
				|  |  | +        (<literal>MethodInvocation</literal>, <literal>JoinPoint</literal> and
 | 
	
		
			
				|  |  |          <literal>FilterInterceptor</literal>) with complete
 | 
	
		
			
				|  |  |          transparency.</para>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -214,7 +214,7 @@
 | 
	
		
			
				|  |  |        <sect2 id="security-high-level-design-supported-secure-objects">
 | 
	
		
			
				|  |  |          <title>Supported Secure Objects</title>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        <para>The Acegi Security System for Spring currently supports two
 | 
	
		
			
				|  |  | +        <para>The Acegi Security System for Spring currently supports three
 | 
	
		
			
				|  |  |          secure objects.</para>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          <para>The first handles an AOP Alliance
 | 
	
	
		
			
				|  | @@ -224,12 +224,24 @@
 | 
	
		
			
				|  |  |          standard Spring-hosted bean available as a
 | 
	
		
			
				|  |  |          <literal>MethodInvocation</literal>, the bean is simply published
 | 
	
		
			
				|  |  |          through a <literal>ProxyFactoryBean</literal> or
 | 
	
		
			
				|  |  | -        <literal>BeanNameAutoProxyCreator</literal>. Most Spring developers
 | 
	
		
			
				|  |  | -        would already be familiar with these due to their use in transactions
 | 
	
		
			
				|  |  | -        and other areas of Spring.</para>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        <para>The second type is a <literal>FilterInvocation</literal>. This
 | 
	
		
			
				|  |  | -        is an object included with the Acegi Security System for Spring. It is
 | 
	
		
			
				|  |  | +        <literal>BeanNameAutoProxyCreator</literal> or
 | 
	
		
			
				|  |  | +        <literal>DefaultAdvisorAutoProxyCreator</literal>. Most Spring
 | 
	
		
			
				|  |  | +        developers would already be familiar with these due to their use in
 | 
	
		
			
				|  |  | +        transactions and other areas of Spring.</para>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <para>The second type is an AspectJ <literal>JoinPoint</literal>.
 | 
	
		
			
				|  |  | +        AspectJ has a particular use in securing domain object instances, as
 | 
	
		
			
				|  |  | +        these are most often managed outside the Spring bean container. By
 | 
	
		
			
				|  |  | +        using AspectJ, standard constructs such as <literal>new
 | 
	
		
			
				|  |  | +        Person();</literal> can be used and full security will be applied to
 | 
	
		
			
				|  |  | +        them by Acegi Security. The
 | 
	
		
			
				|  |  | +        <literal>AspectJSecurityInterceptor</literal> is still managed by
 | 
	
		
			
				|  |  | +        Spring, which creates the aspect singleton and wires it with the
 | 
	
		
			
				|  |  | +        appropriate authentication managers, access decision managers and so
 | 
	
		
			
				|  |  | +        on.</para>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <para>The third type is a <literal>FilterInvocation</literal>. This is
 | 
	
		
			
				|  |  | +        an object included with the Acegi Security System for Spring. It is
 | 
	
		
			
				|  |  |          created by an included filter and simply wraps the HTTP
 | 
	
		
			
				|  |  |          <literal>ServletRequest</literal>, <literal>ServletResponse</literal>
 | 
	
		
			
				|  |  |          and <literal>FilterChain</literal>. The
 | 
	
	
		
			
				|  | @@ -410,9 +422,8 @@
 | 
	
		
			
				|  |  |            </listitem>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |            <listitem>
 | 
	
		
			
				|  |  | -            <para>Call a secure object-specific
 | 
	
		
			
				|  |  | -            <literal>SecurityInterceptorCallback</literal> so that the request
 | 
	
		
			
				|  |  | -            execution can proceed.</para>
 | 
	
		
			
				|  |  | +            <para>Proceed with the request execution of the secure
 | 
	
		
			
				|  |  | +            object.</para>
 | 
	
		
			
				|  |  |            </listitem>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |            <listitem>
 | 
	
	
		
			
				|  | @@ -424,8 +435,8 @@
 | 
	
		
			
				|  |  |            </listitem>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |            <listitem>
 | 
	
		
			
				|  |  | -            <para>Return any result received from the
 | 
	
		
			
				|  |  | -            <literal>SecurityInterceptorCallback</literal>.</para>
 | 
	
		
			
				|  |  | +            <para>Return any result received from the secure object
 | 
	
		
			
				|  |  | +            execution.</para>
 | 
	
		
			
				|  |  |            </listitem>
 | 
	
		
			
				|  |  |          </orderedlist>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -441,8 +452,8 @@
 | 
	
		
			
				|  |  |          object-specific security interceptors are discussed below.</para>
 | 
	
		
			
				|  |  |        </sect2>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -      <sect2 id="security-interception-methodinvocation">
 | 
	
		
			
				|  |  | -        <title>MethodInvocation Security Interceptor</title>
 | 
	
		
			
				|  |  | +      <sect2 id="security-interception-aopalliance">
 | 
	
		
			
				|  |  | +        <title>AOP Alliance (MethodInvocation) Security Interceptor</title>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          <para>To secure <literal>MethodInvocation</literal>s, developers
 | 
	
		
			
				|  |  |          simply add a properly configured
 | 
	
	
		
			
				|  | @@ -452,10 +463,15 @@
 | 
	
		
			
				|  |  |          <literal>ProxyFactoryBean</literal> or
 | 
	
		
			
				|  |  |          <literal>BeanNameAutoProxyCreator</literal>, as commonly used by many
 | 
	
		
			
				|  |  |          other parts of Spring (refer to the sample application for examples).
 | 
	
		
			
				|  |  | -        The <literal>MethodSecurityInterceptor</literal> is configured as
 | 
	
		
			
				|  |  | +        Alternatively, Acegi Security provides a
 | 
	
		
			
				|  |  | +        <literal>MethodDefinitionSourceAdvisor</literal> which may be used
 | 
	
		
			
				|  |  | +        with Spring's <literal>DefaultAdvisorAutoProxyCreator</literal> to
 | 
	
		
			
				|  |  | +        automatically chain the security interceptor in front of any beans
 | 
	
		
			
				|  |  | +        defined against the <literal>MethodSecurityInterceptor</literal>. The
 | 
	
		
			
				|  |  | +        <literal>MethodSecurityInterceptor</literal> itself is configured as
 | 
	
		
			
				|  |  |          follows:</para>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        <para><programlisting><bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
 | 
	
		
			
				|  |  | +        <para><programlisting><bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
 | 
	
		
			
				|  |  |    <property name="validateConfigAttributes"><value>true</value></property>
 | 
	
		
			
				|  |  |    <property name="authenticationManager"><ref bean="authenticationManager"/></property>
 | 
	
		
			
				|  |  |    <property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
 | 
	
	
		
			
				|  | @@ -572,6 +588,124 @@
 | 
	
		
			
				|  |  |          <literal>false</literal>.</para>
 | 
	
		
			
				|  |  |        </sect2>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +      <sect2 id="security-interception-aspectj">
 | 
	
		
			
				|  |  | +        <title>AspectJ (JoinPoint) Security Interceptor</title>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <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
 | 
	
		
			
				|  |  | +        <literal>MethodSecurityInterceptor</literal> 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>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <para><programlisting><bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor">
 | 
	
		
			
				|  |  | +  <property name="validateConfigAttributes"><value>true</value></property>
 | 
	
		
			
				|  |  | +  <property name="authenticationManager"><ref bean="authenticationManager"/></property>
 | 
	
		
			
				|  |  | +  <property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
 | 
	
		
			
				|  |  | +  <property name="runAsManager"><ref bean="runAsManager"/></property>
 | 
	
		
			
				|  |  | +  <property name="objectDefinitionSource">
 | 
	
		
			
				|  |  | +    <value>
 | 
	
		
			
				|  |  | +      net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
 | 
	
		
			
				|  |  | +      net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
 | 
	
		
			
				|  |  | +    </value>
 | 
	
		
			
				|  |  | +  </property>
 | 
	
		
			
				|  |  | +</bean></programlisting></para>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <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>objectDefinitionSource</literal>, as the
 | 
	
		
			
				|  |  | +        <literal>ObjectDefinitionSource</literal> 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
 | 
	
		
			
				|  |  | +        <literal>MethodInvocation</literal> 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>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <para><programlisting>package net.sf.acegisecurity.samples.aspectj;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor;
 | 
	
		
			
				|  |  | +import net.sf.acegisecurity.intercept.method.aspectj.AspectJCallback;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.InitializingBean;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private AspectJSecurityInterceptor securityInterceptor;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  pointcut domainObjectInstanceExecution(): target(PersistableEntity) 
 | 
	
		
			
				|  |  | +             && execution(public * *(..)) && !within(DomainObjectInstanceSecurityAspect);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Object around(): domainObjectInstanceExecution() {
 | 
	
		
			
				|  |  | +    if (this.securityInterceptor != null) {
 | 
	
		
			
				|  |  | +      AspectJCallback callback = new AspectJCallback() {
 | 
	
		
			
				|  |  | +        public Object proceedWithObject() {
 | 
	
		
			
				|  |  | +        return proceed();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return this.securityInterceptor.invoke(thisJoinPoint, callback);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      return proceed();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  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>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <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>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <para><programlisting><bean id="domainObjectInstanceSecurityAspect" 
 | 
	
		
			
				|  |  | +    class="net.sf.acegisecurity.samples.aspectj.DomainObjectInstanceSecurityAspect"
 | 
	
		
			
				|  |  | +    factory-method="aspectOf">
 | 
	
		
			
				|  |  | +  <property name="securityInterceptor"><ref bean="aspectJSecurityInterceptor"/></property>
 | 
	
		
			
				|  |  | +</bean></programlisting></para>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <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>
 | 
	
		
			
				|  |  | +      </sect2>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        <sect2 id="security-interception-filterinvocation">
 | 
	
		
			
				|  |  |          <title>FilterInvocation Security Interceptor</title>
 | 
	
		
			
				|  |  |  
 |