1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.context.rmi;
17
18 import org.acegisecurity.context.SecurityContext;
19 import org.acegisecurity.context.SecurityContextHolder;
20 import org.acegisecurity.context.SecurityContextImpl;
21
22 import org.aopalliance.intercept.MethodInvocation;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import org.springframework.remoting.support.RemoteInvocation;
28
29 import java.lang.reflect.InvocationTargetException;
30
31
32 /***
33 * The actual <code>RemoteInvocation</code> that is passed from the client to
34 * the server, which contains the contents of {@link SecurityContextHolder},
35 * being a {@link SecurityContext} object.
36 *
37 * <p>
38 * When constructed on the client via {@link
39 * org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory},
40 * the contents of the <code>SecurityContext</code> are stored inside the
41 * object. The object is then passed to the server that is processing the
42 * remote invocation. Upon the server invoking the remote invocation, it will
43 * retrieve the passed contents of the <code>SecurityContextHolder</code> and
44 * set them to the server-side <code>SecurityContextHolder</code> whilst the
45 * target object is invoked. When the target invocation has been completed,
46 * the server-side <code>SecurityContextHolder</code> will be reset to a new
47 * instance of <code>SecurityContextImpl</code>.
48 * </p>
49 *
50 * @author James Monaghan
51 * @author Ben Alex
52 * @version $Id: ContextPropagatingRemoteInvocation.java,v 1.7 2005/11/23 16:09:44 luke_t Exp $
53 */
54 public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
55
56
57 private static final Log logger = LogFactory.getLog(ContextPropagatingRemoteInvocation.class);
58
59
60
61 private SecurityContext securityContext;
62
63
64
65 /***
66 * Constructs the object, storing the value of the client-side
67 * <code>SecurityContextHolder</code> inside the object.
68 *
69 * @param methodInvocation the method to invoke
70 */
71 public ContextPropagatingRemoteInvocation(MethodInvocation methodInvocation) {
72 super(methodInvocation);
73 securityContext = SecurityContextHolder.getContext();
74
75 if (logger.isDebugEnabled()) {
76 logger.debug("RemoteInvocation now has SecurityContext: "
77 + securityContext);
78 }
79 }
80
81
82
83 /***
84 * Invoked on the server-side as described in the class JavaDocs.
85 *
86 * <p>
87 * Invocations will always have their {@link
88 * org.acegisecurity.Authentication#setAuthenticated(boolean)} set to
89 * <code>false</code>, which is guaranteed to always be accepted by
90 * <code>Authentication</code> implementations. This ensures that even
91 * remotely authenticated <code>Authentication</code>s will be untrusted
92 * by the server-side, which is an appropriate security measure.
93 * </p>
94 *
95 * @param targetObject the target object to apply the invocation to
96 *
97 * @return the invocation result
98 *
99 * @throws NoSuchMethodException if the method name could not be resolved
100 * @throws IllegalAccessException if the method could not be accessed
101 * @throws InvocationTargetException if the method invocation resulted in
102 * an exception
103 */
104 public Object invoke(Object targetObject)
105 throws NoSuchMethodException, IllegalAccessException,
106 InvocationTargetException {
107 SecurityContextHolder.setContext(securityContext);
108
109 if ((SecurityContextHolder.getContext() != null)
110 && (SecurityContextHolder.getContext().getAuthentication() != null)) {
111 SecurityContextHolder.getContext().getAuthentication()
112 .setAuthenticated(false);
113 }
114
115 if (logger.isDebugEnabled()) {
116 logger.debug("Set SecurityContextHolder to contain: "
117 + securityContext);
118 }
119
120 try {
121
122 return super.invoke(targetObject);
123
124 } finally {
125
126 SecurityContextHolder.setContext(new SecurityContextImpl());
127
128 if (logger.isDebugEnabled()) {
129 logger.debug(
130 "Set SecurityContext to new instance of SecurityContextImpl");
131 }
132 }
133 }
134 }