View Javadoc

1   package org.astrogrid.security;
2   
3   import java.util.Iterator;
4   import javax.security.auth.Subject;
5   import javax.xml.rpc.handler.MessageContext;
6   import javax.xml.rpc.JAXRPCException;
7   import javax.xml.soap.SOAPMessage;
8   
9   
10  /***
11   * A JAX-RPC handler for security credentials.
12   *
13   * This is a client side handler that works on request messages only.
14   * Response messages are passed through unchanged.
15   *
16   * The credentials to be set in the SOAP messages are derived from
17   * properties of a JAAS Subject that is set as a
18   * resource in the initialization of this handler.
19   *
20   * @author Guy Rixon
21   */
22  public class ClientCredentialHandler extends CredentialHandler {
23  
24    /***
25     * Adds security headers to an outgoing message.
26     *
27     * @param mc the context containing the message to which the
28     *          SOAP header-block is added.
29     *
30     * @return true, to allow further processing of the message.
31     *         This handler never returns false to stop processing.
32     *
33     * @throws JAXRPCException if the message context is inappropriate
34     * @throws JAXRPCException if the construction of the header fails
35     */
36    public final boolean handleRequest (final MessageContext mc) {
37      System.out.println("Entering ClientCredentialHandler.handleRequest()");
38      SOAPMessage sm = this.getMessage(mc);
39      assert (sm != null);
40  
41      // Write a WS-Security header.
42      try {
43        assert(this.subject != null);
44        WsseHeaderElement.write(this.getSubject(), sm);
45      }
46      catch (Exception e1) {
47        System.out.println(e1);
48        throw new JAXRPCException("Failed to write a WS-Security header", e1);
49      }
50  
51      return true;
52    }
53  
54  
55    /***
56     * Extracts a JAAS subject containing the credentials.
57     * This method takes care of the use of NonceTokens, which need to
58     * be "split" before use in a message; the returned subject is a
59     * derivative of the Subject stored in the object, not a reference to
60     * that stored Subject.
61     */
62    private Subject getSubject () {
63      System.out.println("Entering ClientCredentialHandler.getSubject()");
64      try {
65  
66        // Clone the existing, shared Subject.
67        Subject subject = new Subject(false,
68                                      this.subject.getPrincipals(),
69                                      this.subject.getPublicCredentials(),
70                                      this.subject.getPrivateCredentials());
71  
72        // Find any NonceTokens in the subjects.
73        Iterator credentials
74            = subject.getPrivateCredentials(NonceToken.class).iterator();
75        while (credentials.hasNext()) {
76          NonceToken n1 = (NonceToken) credentials.next();
77          NonceToken n2 = n1.split();
78          subject.getPrivateCredentials().remove(n1);
79          subject.getPrivateCredentials().add(n2);
80        }
81  
82        return subject;
83      } catch (Exception e) {
84        String message = "Failed to prepare credentials "
85                       + "(failed to split a NonceToken)";
86        System.out.println(message);
87        System.out.println("Cause:");
88        System.out.println(e.toString());
89        throw new JAXRPCException(message, e);
90      }
91    }
92  
93  }