1 package org.astrogrid.applications.service.v1.cea;
2
3 import org.astrogrid.security.SecurityGuard;
4
5 /***
6 * A specialization of SecurityGuard for use in CEA services.
7 *
8 * It is sometimes necessary to get at the authenticated principals
9 * and credentials from the method that implements an CEA application.
10 * That method typically runs in a separate thread from the web-service
11 * invocation that launched it; therefore, the working method cannot call
12 * AxisClientSecurityGuard.getInstanceFromContext() to get the guard object.
13 * This class offers a form of getInstanceFromContext() that works between
14 * threads, such that a guard may be cached in the web-service invocation
15 * and retrieved in the worker thread.
16 *
17 * The mechanism uses java.lang.InheritableThreadLocal to cache one
18 * instance of this class per thread. Assuming that each invocation of the
19 * web service runs in a separate thread, this is then well-behaved for
20 * concurrent invocations of the web-service. Any worker thread created
21 * by a web-service thread inherits a copy of the guard cached by the
22 * latter. If worker threads are not used - i.e. if the application code
23 * is executed directly from the web-service thread - then the correct guard
24 * is still retrieved from the cache.
25 *
26 * @author Guy Rixon
27 */
28 public class CeaSecurityGuard extends SecurityGuard {
29
30 /***
31 * The cached guard-object. When accessed, the cache for a given thread
32 * always contains an object that was explicitly put in, or, failing that,
33 * one created on the fly using the anonymous, inner class below. In the
34 * latter case, the guard has no principals or credentials and expresses
35 * a lack of authentication.
36 */
37 private static InheritableThreadLocal store
38 = new InheritableThreadLocal() {
39 protected synchronized Object initialValue() {
40 return new CeaSecurityGuard();
41 }
42 };
43
44 /*** Creates a new instance of CeaSecurityGuard */
45 public CeaSecurityGuard() {
46 super();
47 }
48
49 public CeaSecurityGuard(SecurityGuard g) {
50 super(g);
51 }
52
53 public static void setInstanceInContext(SecurityGuard g1) {
54 CeaSecurityGuard g2 = new CeaSecurityGuard(g1);
55 CeaSecurityGuard.store.set(g2);
56 }
57
58 /***
59 * Fetch the guard from the cache. If nothing is in the cache,
60 * creates a new guard with no credentials or principals.
61 *
62 * @return - the guard (never null).
63 */
64 public static CeaSecurityGuard getInstanceFromContext() {
65 return (CeaSecurityGuard)(CeaSecurityGuard.store.get());
66 }
67
68 /***
69 * Tests whether the current call to the web service has been
70 * authenticated. Assumes that an X500Principal will have been
71 * recorded in any successful authentication.
72 *
73 * @return true if the call is anonymous
74 */
75 public boolean isAuthenticated() {
76 return (this.getX500Principal() != null);
77 }
78
79 }