View Javadoc

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  }