View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.processor;
21  
22  import org.apache.ws.security.WSConstants;
23  import org.apache.ws.security.WSDocInfo;
24  import org.apache.ws.security.WSPasswordCallback;
25  import org.apache.ws.security.WSSecurityEngineResult;
26  import org.apache.ws.security.WSSecurityException;
27  import org.apache.ws.security.handler.RequestData;
28  import org.apache.ws.security.message.token.SecurityContextToken;
29  import org.apache.ws.security.validate.Credential;
30  import org.apache.ws.security.validate.Validator;
31  import org.w3c.dom.Element;
32  
33  import javax.security.auth.callback.Callback;
34  import javax.security.auth.callback.CallbackHandler;
35  import javax.security.auth.callback.UnsupportedCallbackException;
36  import javax.xml.namespace.QName;
37  
38  import java.util.List;
39  import java.io.IOException;
40  
41  /**
42   * The processor to process <code>wsc:SecurityContextToken</code>.
43   * 
44   * @author Ruchith Fernando (ruchith.fernando@gmail.com)
45   */
46  public class SecurityContextTokenProcessor implements Processor {
47      
48      public List<WSSecurityEngineResult> handleToken(
49          Element elem, 
50          RequestData data,
51          WSDocInfo wsDocInfo 
52      ) throws WSSecurityException {
53          SecurityContextToken sct = new SecurityContextToken(elem);
54          
55          Validator validator = 
56              data.getValidator(new QName(elem.getNamespaceURI(), elem.getLocalName()));
57  
58          WSSecurityEngineResult result =
59              new WSSecurityEngineResult(WSConstants.SCT, sct);
60          if (validator != null) {
61              // Hook to allow the user to validate the SecurityContextToken
62              Credential credential = new Credential();
63              credential.setSecurityContextToken(sct);
64              
65              Credential returnedCredential = validator.validate(credential, data);
66              result.put(WSSecurityEngineResult.TAG_VALIDATED_TOKEN, Boolean.TRUE);
67              result.put(WSSecurityEngineResult.TAG_ID, sct.getID());
68              result.put(WSSecurityEngineResult.TAG_SECRET, returnedCredential.getSecretKey());
69          } else {
70              String id = sct.getID();
71              if (id.charAt(0) == '#') {
72                  id = id.substring(1);
73              }
74              byte[] secret = null;
75              try {
76                  secret = getSecret(data.getCallbackHandler(), sct.getIdentifier());
77              } catch (WSSecurityException ex) {
78                  secret = getSecret(data.getCallbackHandler(), id);
79              }
80              if (secret == null || secret.length == 0) {
81                  secret = getSecret(data.getCallbackHandler(), id);
82              }
83              result.put(WSSecurityEngineResult.TAG_ID, sct.getID());
84              result.put(WSSecurityEngineResult.TAG_SECRET, secret);
85          }
86          
87          wsDocInfo.addTokenElement(elem);
88          wsDocInfo.addResult(result);
89          return java.util.Collections.singletonList(result);
90      }
91  
92      /**
93       * Get the secret from the provided callback handler and return it.
94       * 
95       * @param cb
96       * @param sct
97       * @return The key collected using the callback handler
98       */
99      private byte[] getSecret(CallbackHandler cb, String identifier)
100         throws WSSecurityException {
101 
102         if (cb == null) {
103             throw new WSSecurityException(WSSecurityException.FAILURE, "noCallback");
104         }
105 
106         WSPasswordCallback callback = 
107             new WSPasswordCallback(identifier, WSPasswordCallback.SECURITY_CONTEXT_TOKEN);
108         try {
109             Callback[] callbacks = new Callback[]{callback};
110             cb.handle(callbacks);
111         } catch (IOException e) {
112             throw new WSSecurityException(
113                 WSSecurityException.FAILURE, 
114                 "noKey",
115                 new Object[] {identifier}, 
116                 e
117             );
118         } catch (UnsupportedCallbackException e) {
119             throw new WSSecurityException(
120                 WSSecurityException.FAILURE, 
121                 "noKey",
122                 new Object[] {identifier}, 
123                 e
124             );
125         }
126 
127         return callback.getKey();
128     }
129 
130 }