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.wss4j.dom.message.token;
21  
22  import javax.xml.namespace.QName;
23  
24  import org.apache.wss4j.dom.WSConstants;
25  import org.apache.wss4j.common.ext.WSSecurityException;
26  import org.apache.wss4j.common.util.DOM2Writer;
27  import org.apache.wss4j.common.util.XMLUtils;
28  import org.apache.wss4j.common.derivedKey.ConversationConstants;
29  import org.apache.xml.security.stax.impl.util.IDGenerator;
30  import org.w3c.dom.Document;
31  import org.w3c.dom.Element;
32  import org.w3c.dom.Node;
33  import org.w3c.dom.Text;
34  
35  public class SecurityContextToken {
36  
37      /**
38       * Security context token element
39       */
40      private Element element;
41  
42      /**
43       * Identifier element
44       */
45      private Element elementIdentifier;
46  
47      /**
48       * Instance element
49       */
50      private Element elementInstance;
51  
52      private String tokenType = WSConstants.WSC_SCT;
53  
54      /**
55       * Constructor to create the SCT
56       *
57       * @param doc
58       */
59      public SecurityContextToken(Document doc) throws WSSecurityException {
60          this(ConversationConstants.DEFAULT_VERSION, doc);
61      }
62  
63      /**
64       * Constructor to create the SCT with a given uuid
65       *
66       * @param doc
67       */
68      public SecurityContextToken(Document doc, String uuid) throws WSSecurityException {
69          this(ConversationConstants.DEFAULT_VERSION, doc, uuid);
70      }
71  
72      /**
73       * Constructor to create the SCT
74       *
75       * @param doc
76       */
77      public SecurityContextToken(int version, Document doc) throws WSSecurityException {
78  
79          String ns = ConversationConstants.getWSCNs(version);
80  
81          element =
82              doc.createElementNS(ns, "wsc:" + ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
83  
84          XMLUtils.setNamespace(element, ns, ConversationConstants.WSC_PREFIX);
85  
86          elementIdentifier =
87              doc.createElementNS(ns, "wsc:" + ConversationConstants.IDENTIFIER_LN);
88  
89          element.appendChild(elementIdentifier);
90  
91          String uuid = IDGenerator.generateID("uuid:");
92  
93          elementIdentifier.appendChild(doc.createTextNode(uuid));
94      }
95  
96      /**
97       * Constructor to create the SCT with a given uuid
98       *
99       * @param doc
100      */
101     public SecurityContextToken(int version, Document doc, String uuid) throws WSSecurityException {
102 
103         String ns = ConversationConstants.getWSCNs(version);
104 
105         element =
106             doc.createElementNS(ns, "wsc:" + ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
107 
108         XMLUtils.setNamespace(element, ns, ConversationConstants.WSC_PREFIX);
109 
110         elementIdentifier =
111             doc.createElementNS(ns, "wsc:" + ConversationConstants.IDENTIFIER_LN);
112 
113         element.appendChild(elementIdentifier);
114 
115         elementIdentifier.appendChild(doc.createTextNode(uuid));
116 
117         if (version == ConversationConstants.VERSION_05_02) {
118             tokenType = WSConstants.WSC_SCT;
119         } else {
120             tokenType = WSConstants.WSC_SCT_05_12;
121         }
122     }
123 
124     /**
125      * Constructor to create the SCT with a given uuid and instance
126      *
127      * @param doc
128      */
129     public SecurityContextToken(int version, Document doc, String uuid, String instance)
130         throws WSSecurityException {
131         this(version, doc, uuid);
132 
133         if (instance != null) {
134             String ns = ConversationConstants.getWSCNs(version);
135             elementInstance = doc.createElementNS(ns, ConversationConstants.INSTANCE_LN);
136             element.appendChild(elementInstance);
137             elementInstance.appendChild(doc.createTextNode(instance));
138         }
139     }
140 
141     /**
142      * This is used to create a SecurityContextToken using a DOM Element
143      *
144      * @param elem The DOM element: The security context token
145      * @throws WSSecurityException If the element passed in in not a security context token
146      */
147     public SecurityContextToken(Element elem) throws WSSecurityException {
148         element = elem;
149         QName el = new QName(element.getNamespaceURI(), element.getLocalName());
150 
151         // If the element is not a security context token, throw an exception
152         if (el.equals(ConversationConstants.SECURITY_CTX_TOKEN_QNAME_05_02)) {
153             tokenType = WSConstants.WSC_SCT;
154         } else if (el.equals(ConversationConstants.SECURITY_CTX_TOKEN_QNAME_05_12)) {
155             tokenType = WSConstants.WSC_SCT_05_12;
156         } else {
157             throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN);
158         }
159 
160         elementIdentifier =
161             XMLUtils.getDirectChildElement(
162                 element,
163                 ConversationConstants.IDENTIFIER_LN,
164                 el.getNamespaceURI()
165             );
166 
167         elementInstance =
168             XMLUtils.getDirectChildElement(
169                 element,
170                 ConversationConstants.INSTANCE_LN,
171                 el.getNamespaceURI()
172             );
173     }
174 
175     /**
176      * Add the WSU Namespace to this SCT. The namespace is not added by default for
177      * efficiency purposes.
178      */
179     public void addWSUNamespace() {
180         element.setAttributeNS(XMLUtils.XMLNS_NS, "xmlns:" + WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
181     }
182 
183     /**
184      * Set the identifier.
185      */
186     public void setIdentifier(String uuid) {
187         Text node = getFirstNode(elementIdentifier);
188         node.setData(uuid);
189     }
190 
191     /**
192      * Get the identifier.
193      *
194      * @return the data from the identifier element.
195      */
196     public String getIdentifier() {
197         if (elementIdentifier != null) {
198             Text text = getFirstNode(elementIdentifier);
199             if (text != null) {
200                 return text.getData();
201             }
202         }
203         return null;
204     }
205 
206     /**
207      * Get the instance.
208      *
209      * @return the data from the instance element.
210      */
211     public String getInstance() {
212         if (elementInstance != null) {
213             Text text = getFirstNode(elementInstance);
214             if (text != null) {
215                 return text.getData();
216             }
217         }
218         return null;
219     }
220 
221     /**
222      * Get the WS-Trust tokenType String associated with this token
223      */
224     public String getTokenType() {
225         return tokenType;
226     }
227 
228     public void setElement(Element elem) {
229         element.appendChild(elem);
230     }
231 
232     /**
233      * Returns the first text node of an element.
234      *
235      * @param e the element to get the node from
236      * @return the first text node or <code>null</code> if node
237      *         is null or is not a text node
238      */
239     private Text getFirstNode(Element e) {
240         Node node = e.getFirstChild();
241         return node != null && Node.TEXT_NODE == node.getNodeType() ? (Text) node : null;
242     }
243 
244     /**
245      * Returns the dom element of this <code>SecurityContextToken</code> object.
246      *
247      * @return the <code>wsse:SecurityContextToken</code> element
248      */
249     public Element getElement() {
250         return element;
251     }
252 
253     /**
254      * Returns the string representation of the token.
255      *
256      * @return a XML string representation
257      */
258     public String toString() {
259         return DOM2Writer.nodeToString(element);
260     }
261 
262     /**
263      * Gets the id.
264      *
265      * @return the value of the <code>wsu:Id</code> attribute of this
266      *         SecurityContextToken
267      */
268     public String getID() {
269         return element.getAttributeNS(WSConstants.WSU_NS, "Id");
270     }
271 
272     /**
273      * Set the id of this security context token.
274      *
275      * @param id the value for the <code>wsu:Id</code> attribute of this
276      *           SecurityContextToken
277      */
278     public void setID(String id) {
279         element.setAttributeNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":Id", id);
280     }
281 
282     @Override
283     public int hashCode() {
284         int result = 17;
285         String identifier = getIdentifier();
286         if (identifier != null) {
287             result = 31 * result + identifier.hashCode();
288         }
289         return result;
290     }
291 
292     @Override
293     public boolean equals(Object object) {
294         if (!(object instanceof SecurityContextToken)) {
295             return false;
296         }
297         SecurityContextToken securityToken = (SecurityContextToken)object;
298         return compare(getIdentifier(), securityToken.getIdentifier());
299     }
300 
301     private boolean compare(String item1, String item2) {
302         if (item1 == null && item2 != null) {
303             return false;
304         } else if (item1 != null && !item1.equals(item2)) {
305             return false;
306         }
307         return true;
308     }
309 
310 }