diff --git a/src/docbkx/springsecurity.xml b/src/docbkx/springsecurity.xml
index 004546a61c..85cb154806 100644
--- a/src/docbkx/springsecurity.xml
+++ b/src/docbkx/springsecurity.xml
@@ -4485,376 +4485,6 @@ $CATALINA_HOME/bin/startup.sh
Finally, restart Tomcat.
-
-
- Context propagation support for EJBs
-
-
- Rationale
-
- Spring Security does provide transparent propagation of security
- context information in specific remoting scenarios. That means that
- the security context of the invoker is passed along with each method
- invocation to the server. There the context is being reestablished so
- that a service method can take place in the security context of the
- invoker. There is out-of-the-box support for RMI or Spring's own
- HttpInvoker protocol. Now many applications around are based on EJB
- remoting because of requirements or policy, which are precluded from
- that benefit.
-
- If you have an EJB application you have two options for
- integrating Spring Security:
-
-
-
- Use a container adapter for integrating with that
- application server's proprietary security mechanism (Spring
- Security provides some ready usable adapters for use in legacy
- scenarios)
-
-
-
- Create wrappers on the client side (and on the server side
- when using POJO delegation) to propagate the security
- context
-
-
-
- Both approaches have the benefit that the implementation of your
- service, as well as its clients, are agnostic to remoting and security
- context propagation taking place. The drawback of the first approach
- is, that you have to reimplement parts of your security infrastructure
- when switching the container (or maybe upgrading it, as sometimes the
- security strategy changes over time). That issue does not arise in the
- second approach, but the problem here is the implementation overhead
- of creating according wrappers to hide the context propagation.
-
- The following chapters describe the infrastructure classes which
- wrap the context propagation and abstract it away from both client
- usage and service implementation.
-
-
-
- How it works
-
- See figure 1 which describes the recommended POJO delegation
- model, where an EJB session bean only serves as remoting wrapper. The
- actual service implementation resides inside a POJO that implements
- the given business interface. The EJB implementation does nothing more
- than just delegating invocations of service operations to the POJO.
- Using Spring's support classes for wiring the POJO to the EJB is
- simple. Spring also allows wiring the service interface to the client
- by transparently wrapping the remote interface.
-
-
- Figure 1: Using EJB as remoting wrapper
-
-
-
-
-
-
-
-
- This concept is now slightly enhanced by the context propagation
- module. As it is not possible to intercept the invocation of a remote
- interface in a portable manner, we have to extend the remote interface
- methods to include an additional parameter that holdes the
- SecurityContext we wish to propagate. In consequence we also have to
- modify the method implementations in the EJB implementation class to
- take that additional argument. This is depicted in figure 2. Note
- however, that the client still works with the plain business interface
- we had before and that the actual service implementation class is
- still the same.
-
-
- Figure 2: Using EJB as enhanced remoting wrapper
-
-
-
-
-
-
-
-
- Now how does this work? On the client side a proxy translates
- invocations from the business interface (Service) to invocations of
- the extended business interface (XService) which is actually exposed
- by the remote interface. The current security context is extracted and
- passed into the additionally provided method parameter.
-
- On the server side the EJB implementation refers to a delegate
- which also exposes the extended service interface (XService). Behind
- that service interface hides a proxy which extracts the passed-in
- SecurityContext and establishes it in the current thread. Then it
- delegates the invocation to the actual delegate class (ServiceImpl),
- translating the method invocation as the target does not know about
- the SecurityContext parameter. The invocation chain is exemplified in
- figure 3.
-
-
- Figure 3: Invocation chain
-
-
-
-
-
-
- The yellow colored elements indicate instances exposing the
- extended business interface while the green colored elements indicate
- instances exposing the real business interface.
-
-
-
- How to use it
-
- The following subsections show how to use the provided
- infrastructure classes and how to enable your code to use them.
-
-
- The building blocks
-
-
- The business interface
-
- public interface Service {
-
- Result operation(Parameter param);
- }How the business interface looks like depends just on,
- well, your business requirements. Nothing special about it.
-
-
-
- The service implementation
-
- public class ServiceImpl implements Service {
-
- public Result operation(Parameter param) {
- ...
- }
- }The service implementation just implements the business
- interface, nothing more.
-
-
-
- The extended business interface and the remote
- interface
-
- // Extended business interface
- public interface XService {
-
- public Result operation(SecurityContext securityCtx, Parameter param) throws SecurityServiceException, RemoteException;
- }
-
- // Remote interface
- public interface ServiceRemote extends XService, EJBObject {}The
- extended business interface introduces an additional parameter for
- each method (which is by convention the first parameter). Besides
- that augmentation of the parameter list we have to consider that
- this interface is being used in an EJB remoting scenario, so we
- specify a "throws RemoteException" for each method. This is not
- strictly necessary but it allows us to greatly simplify the
- definition of the actual remote interface as could be seen in the
- second listing.
-
- In addition to the RemoteException, each method also should
- declare throwing a
- org.springframework.security.ejb.server.SecurityServiceException.
- This is because of the EJB spec: If an EJB method throws an
- unchecked exception (all Spring Security exceptions are unchecked)
- that exception will be wrapped into a RemoteException and the bean
- instance will be dropped from the container. As this is unwanted
- and negatively impacts performance we declare the
- SecurityServiceException to be thrown. So any security exceptions
- will be wrapped into a SecurityServiceException to be passed to
- the client. Note that everything still works when that declaration
- is omitted, but consider the negative consequences for the EJB in
- question.
-
-
-
- The EJB implementation
-
- public class ServiceBean extends AbstractStatelessSessionBean implements XService {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Delegate bean name.
- */
- private static final String DELEGATE_BEAN_NAME = "xService";
-
- /**
- * The delegate.
- */
- private XService delegate;
-
-
- /**
- * @see org.springframework.ejb.support.AbstractStatelessSessionBean#onEjbCreate()
- */
- protected void onEjbCreate() throws CreateException {
- this.delegate = (XService) getBeanFactory().getBean(DELEGATE_BEAN_NAME, XService.class);
- }
-
- /**
- * @see XService#operation(SecurityContext, Parameter)
- */
- public Result operation(SecurityContext securityCtx, Parameter param) throws SecurityServiceException, RemoteException {
- return this.delegate.operation(ctx, name);
- }
- }
-
- It is recommended to use the convenience
- AbstractStatelessSessionBean base class provided by the Spring
- Framework. Implementation is then reduced to implementing the
- onEjbCreate()-callback method to retrieve the delegate bean and to
- implement the methods to do the delegation.
-
-
-
-
- Wiring the client-side
-
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
-
- <beans>
-
- <bean id="client" class="client.Client">
- <property name="service" ref="service"/>
- </bean>
-
- <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
- <property name="environment">
- <value>
- // ...
- </value>
- </property>
- </bean>
-
- <bean id="service" class="org.springframework.security.ejb.client.SecurityContextInjectingRemoteSlsbProxyFactoryBean">
-
- <property name="businessInterface" value="server.Service"/>
-
- <property name="slsbBusinessInterface" value="server.XService"/>
-
- <property name="jndiTemplate" ref="jndiTemplate"/>
-
- <property name="jndiName" value="ejb/Service"/>
-
- <property name="extraArgumentPosition" value="0"/>
-
- <property name="methodRegexpPatterns">
- <list>
- <value>.*</value>
- </list>
- </property>
-
- </bean>
- </beans>The above listing shows how the the service
- is being wired to the client. Instead of using a
- SimpleRemoteStatelessSessionProxyFactoryBean we use a
- SecurityContextInjectingRemoteSlsbProxyFactoryBean which provides
- the same functionality but is enhanced for hiding context
- propagation.
-
- The specified "businessInterface" property designates the
- actual business interface while the property "slsbBusinessInterface"
- specifies the extended business interface (it conforms to the
- SimpleRemoteStatelessSessionProxyFactoryBean#businessInterface
- property).
-
- The "extraArgumentPosition" and "methodRegexpPatterns"
- properties are optional. The former specifies the index of the
- parameter to insert. The default is 0 which means that the
- SecurityContext parameter will be the first one in the parameter
- list. The latter parameter specifies which methods to enhance by an
- additional SecurityContext parameter. By default all exposed methods
- are enhanced.
-
- Most other properties correspond to those in
- SimpleRemoteStatelessSessionProxyFactoryBean. Please refer to the
- API documentation for more details.
-
-
-
- Wiring the server-side
-
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
-
- <beans>
-
- <!-- Proxy for extracting secure context information -->
- <bean id="xService" class="org.springframework.security.ejb.server.support.SecurityContextExtractingProxyFactoryBean">
-
- <property name="businessInterface" value="server.XService"/>
-
- <property name="interceptorNames">
- <list>
- <value>serviceSecurityInterceptor</value>
- </list>
- </property>
-
- <property name="target" ref="serviceTarget"/>
-
- <property name="extraArgumentPosition" value="0"/>
-
- <property name="methodRegexpPatterns">
- <list>
- <value>.*</value>
- </list>
- </property>
- </bean>
-
- <!-- Security interceptor -->
- <bean id="helloServiceSecurityInterceptor" class="org.springframework.security.ejb.server.support.TranslatingMethodSecurityInterceptor">
- <property name="validateConfigAttributes" value="true"/>
- <property name="authenticationManager" ref="authenticationManager"/>
- <property name="accessDecisionManager" ref="accessDecisionManager"/>
- <property name="runAsManager" ref="runAsManager"/>
-
- <property name="objectDefinitionSource">
- <value>server.Service.*=ROLE_USER</value>
- </property>
- </bean>
-
- <!-- Service implementation -->
- <bean id="serviceTarget" class="server.ServiceImpl">
- </bean>
-
- </beans>
-
- The definition of the EJB's delegate bean (xService) is
- actually a SecurityContextExtractingProxyFactoryBean which creates a
- proxy that takes care of extracting the SecurityContext,
- establishing it, and delegating to the target bean
- (serviceTarget).
-
- The "businessInterface" property is again the extended
- business interface exposed by proxies created by the factory bean.
- The "target" refers to the actual target bean, while the
- "interceptorNames" property refers to a list of interceptor names
- which have to be defined in the application context.
-
- Note that the security interceptor is of type
- "TranslatingMethodSecurityInterceptor". It is a subclass of
- org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor
- and additionaly wraps all security exceptions into a
- SecurityServiceException, if possible. For its parameterization
- refer to the documentation of MethodSecurityInterceptor.
-
- The "extraArgumentPosition" and "methodRegexpPatterns"
- properties are again optional, specifying the position of the
- additional SecurityContext parameter and which methods will be
- augmented by it. It is important that both properties are specified
- the same on client and server. As recommendation just omit
- specifying these properties and stick with the default
- values.
-
-
-