View Javadoc

1   package org.astrogrid.security;
2   
3   import java.util.List;
4   import java.util.Hashtable;
5   import javax.xml.namespace.QName;
6   import javax.xml.rpc.handler.HandlerRegistry;
7   import javax.xml.rpc.handler.HandlerInfo;
8   import javax.xml.rpc.Service;
9   
10  /***
11   * Access to the security tokens pertaining to the client side of
12   * web-service operations.
13   *
14   * A client application may call this class to add security tokens to
15   * outgoing requests to a SOAP service. A web-service implementation
16   * cannot use this class to manipulate tokens passed to it by a client.
17   * However, if service A wishes to act as a client of subsidiary service
18   * B, then A may use this class. See the package description for more
19   * details.
20   *
21   * A client should create one instance of this class for each identity
22   * it needs to use. E.g., if the client wants to invoke one service in
23   * the name of an end-user and a second in the the name of a community,
24   * then it needs two Guards.  However, if the client wants to apply
25   * the same credentials to many services, then it only needs one Guard.
26   * If some of the credentials change between invocations of services
27   * an existing guard should be reused and reprogrammed. Guards are
28   * created using the default, no-argument constructor.
29   *
30   * To set the guard on a web-service endpoint, the client must obtain
31   * a JAX-RPC javax.xml.rpc.Service representing the endpoint and then
32   * call {@link mountGuard}, passing the Service as a
33   * parameter. The client must do this only once for any given Service.
34   * This method sets up the JAX-RPC message-handlers that embed the
35   * credentials in the outgoing message.
36   *
37   * The client sets the credentials by setting Java-bean properties of
38   * the SecurityGuard (i.e. the parent class). After the guard is set,
39   * each outgoing message is augmented with credentials matching the
40   * current settings in the Guard.
41   *
42   * The convenience method {@link signOn} implements single sign-on to
43   * a network using an initial user-name and password. This method signs
44   * on to some portal that supplies the credentials for subsequent access
45   * to services; these credentials are then stored in the properties of
46   * the security guard. Currently, the credentials are a {@link NonceToken}
47   * from the AstroGrid community service.
48   *
49   * @see {@link ClientCredentialHandler}
50   * @see {@link SecurityGuard}
51   * @see javax.xml.rpc.Service
52   *
53   * @author Guy Rixon
54   */
55  public class ClientSecurityGuard extends SecurityGuard {
56  
57    /***
58     * Creates a ClientSecurityGuard. This may instantiate
59     * a subclass of ClientSecurityGuard based on the
60     * system configuration (Abstract Factory pattern).
61     * The guard may be initialized with some properties from
62     * the configuration.
63     *
64     * @return the new guard
65     * @throws Exception if anything goes wrong
66     */
67    public static final ClientSecurityGuard getInstance () throws Exception {
68      // Currently, we have one default implementation,
69      // so can instantiate that without configuration.
70      return new ClientSecurityGuard();
71    }
72  
73    /***
74     * Creates a ClientSecurityGuard. This method is protected
75     * to force applications to use the abstract factory method
76     * {@link getInstance}.
77     */
78    public ClientSecurityGuard () {
79      super();
80    }
81  
82  
83    /***
84     * Sets a guard on a web-service endpoint.
85     * After this method completes, all messages to that
86     * endpoint carry security credentials.
87     * This sets up the message handlers for the endpoint;
88     * this must be done exactly once.
89     *
90     * @param service the endpoint to be guarded
91     * @param port the QName for the port to be guarded
92     */
93    public void mountGuard (Service service, QName port) {
94  
95      // Create the configuration for the handler. This is always the
96      // same and applies to any number of web-service port-types.
97      Hashtable config = new Hashtable();
98      config.put("Subject", this.getGridSubject());
99      QName[] handlers = new QName[] {};
100     HandlerInfo info = new HandlerInfo(ClientCredentialHandler.class,
101                                        config,
102                                        handlers);
103 
104     // Get the JAX-RPC handler-chain for the port and add the
105     // credentials handler from this package.
106     HandlerRegistry reg = service.getHandlerRegistry();
107     System.out.println("Setting the credential handler for " + port);
108     List chain = reg.getHandlerChain(port);
109     chain.add(info);
110   }
111 
112 
113   /***
114    * Signs on to a network, retrieving credentials for subsequent use
115    * of that network. Signs on with the current values of the Username
116    * and Password properties; updates the Username and Password properties.
117    *
118    * @throws Exception if the sign-on fails
119    */
120   public void signOn () throws Exception {
121     String u = this.getSsoUsername();
122     String p = this.getSsoPassword();
123     System.out.println("ClientSecurityGuard.signOn(): signing on to the grid"
124                      + " with account name "
125                      + u);
126     try {
127 	  NonceToken t = NonceToken.signOn(this.getSsoUsername(),
128 	                                   this.getSsoPassword());
129       this.setNonceToken(t);
130     }
131     catch (Exception e) {
132       throw new Exception("Failed to sign on to the grid as " + u, e);
133     }
134   }
135 
136 }