001: /*
002: * $Id: SecurityTokenReference.java,v 1.6 2007/01/08 16:06:10 shyam_rao Exp $
003: */
004:
005: /*
006: * The contents of this file are subject to the terms
007: * of the Common Development and Distribution License
008: * (the License). You may not use this file except in
009: * compliance with the License.
010: *
011: * You can obtain a copy of the license at
012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
013: * See the License for the specific language governing
014: * permissions and limitations under the License.
015: *
016: * When distributing Covered Code, include this CDDL
017: * Header Notice in each file and include the License file
018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
019: * If applicable, add the following below the CDDL Header,
020: * with the fields enclosed by brackets [] replaced by
021: * you own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
025: */
026:
027: package com.sun.xml.wss.core;
028:
029: import com.sun.xml.wss.core.reference.X509ThumbPrintIdentifier;
030: import com.sun.xml.wss.core.reference.EncryptedKeySHA1Identifier;
031: import com.sun.xml.wss.logging.LogDomainConstants;
032: import com.sun.xml.wss.impl.MessageConstants;
033: import com.sun.xml.wss.impl.SecurableSoapMessage;
034: import com.sun.xml.wss.impl.XMLUtil;
035: import com.sun.xml.wss.XWSSecurityException; //import com.sun.xml.wss.saml.assertion.saml11.jaxb10.SAMLUtil;
036: import java.util.Iterator;
037: import java.util.List;
038: import java.util.logging.Level;
039: import java.util.logging.Logger;
040:
041: import javax.xml.soap.SOAPElement;
042: import javax.xml.soap.SOAPException;
043:
044: import org.w3c.dom.Document;
045: import org.w3c.dom.Element;
046: import org.w3c.dom.Node;
047:
048: import com.sun.xml.wss.impl.misc.SecurityHeaderBlockImpl;
049: import com.sun.xml.wss.core.reference.DirectReference;
050: import com.sun.xml.wss.core.reference.KeyIdentifier;
051: import com.sun.xml.wss.core.reference.SamlKeyIdentifier;
052: import com.sun.xml.wss.core.reference.X509IssuerSerial;
053: import com.sun.xml.wss.core.reference.X509SubjectKeyIdentifier;
054:
055: //import com.sun.xml.wss.saml.assertion.saml11.jaxb10.AuthorityBinding;
056:
057: /**
058: * @author Vishal Mahajan
059: */
060: public class SecurityTokenReference extends SecurityHeaderBlockImpl
061: implements com.sun.xml.ws.security.SecurityTokenReference {
062: //implements com.sun.xml.ws.security.SecurityTokenReference {
063:
064: protected static final Logger log = Logger.getLogger(
065: LogDomainConstants.WSS_API_DOMAIN,
066: LogDomainConstants.WSS_API_DOMAIN_BUNDLE);
067:
068: /**
069: * Assumes that there is only one reference child element.
070: */
071: private ReferenceElement refElement;
072: private Element samlAuthorityBinding;
073:
074: private static final String authorityBinding = "AuthorityBinding"
075: .intern();
076:
077: /**
078: * Creates an "empty" SecurityTokenReference element
079: */
080: public SecurityTokenReference() throws XWSSecurityException {
081: try {
082: setSOAPElement(getSoapFactory().createElement(
083: "SecurityTokenReference", "wsse",
084: MessageConstants.WSSE_NS));
085: addNamespaceDeclaration(MessageConstants.WSSE_PREFIX,
086: MessageConstants.WSSE_NS);
087: } catch (SOAPException e) {
088: log.log(Level.SEVERE, "WSS0377.error.creating.str", e
089: .getMessage());
090: throw new XWSSecurityException(e);
091: }
092: }
093:
094: /**
095: * Creates an "empty" SecurityTokenReference element whose owner document
096: * is doc
097: */
098: public SecurityTokenReference(Document doc)
099: throws XWSSecurityException {
100: try {
101: setSOAPElement((SOAPElement) doc
102: .createElementNS(
103: MessageConstants.WSSE_NS,
104: MessageConstants.WSSE_SECURITY_TOKEN_REFERENCE_QNAME));
105: addNamespaceDeclaration(MessageConstants.WSSE_PREFIX,
106: MessageConstants.WSSE_NS);
107: } catch (Exception e) {
108: log.log(Level.SEVERE, "WSS0378.error.creating.str", e
109: .getMessage());
110: throw new XWSSecurityException(e);
111: }
112: }
113:
114: /**
115: * Takes a SOAPElement which has the required structure of a
116: * SecurityTokenReference (including the reference element).
117: */
118: public SecurityTokenReference(SOAPElement element, boolean isBSP)
119: throws XWSSecurityException {
120:
121: super (element);
122:
123: if (!(element.getLocalName().equals("SecurityTokenReference") && XMLUtil
124: .inWsseNS(element))) {
125: log.log(Level.SEVERE, "WSS0379.error.creating.str", element
126: .getTagName());
127: throw new XWSSecurityException("Invalid tokenRef passed");
128: }
129:
130: isBSP(isBSP);
131:
132: Iterator eachChild = getChildElements();
133: if (!eachChild.hasNext()) {
134: throw new XWSSecurityException(
135: "Error: A SECURITY_TOKEN_REFERENCE with No child elements encountered");
136: }
137:
138: javax.xml.soap.Node node = null;
139:
140: // reference mechanisms found in the STR
141: int refMechanismFound = 0;
142:
143: while (eachChild.hasNext()) {
144:
145: if (isBSP && refMechanismFound > 1) {
146: throw new XWSSecurityException(
147: "Violation of BSP R3061: "
148: + " A SECURITY_TOKEN_REFERENCE MUST have exactly one child element");
149: }
150:
151: node = (javax.xml.soap.Node) eachChild.next();
152:
153: if (node == null) {
154: log.log(Level.SEVERE, "WSS0379.error.creating.str");
155: throw new XWSSecurityException(
156: "Passed tokenReference does not contain a refElement");
157: }
158:
159: if (node.getNodeType() != Node.ELEMENT_NODE) {
160: continue;
161: }
162:
163: if (authorityBinding == node.getLocalName()
164: || authorityBinding.equals(node.getLocalName())) {
165: try {
166: if (MessageConstants.debug) {
167: log.log(Level.FINEST,
168: "Unmarshall authorityBinding");
169: }
170: samlAuthorityBinding = (Element) node;
171: } catch (Exception e) {
172: throw new XWSSecurityException(e);
173: }
174: } else {
175: refElement = getReferenceElementfromSoapElement(
176: (SOAPElement) node, isBSP);
177: refMechanismFound = refMechanismFound + 1;
178: }
179: }
180: }
181:
182: public SecurityTokenReference(SOAPElement element)
183: throws XWSSecurityException {
184: this (element, false);
185: }
186:
187: public ReferenceElement getReference() {
188: return refElement;
189: }
190:
191: public void setSamlAuthorityBinding(Element binding, Document doc)
192: throws XWSSecurityException {
193: if (samlAuthorityBinding != null) {
194: throw new XWSSecurityException(
195: " SAML AuthorityBinding element is already present");
196: }
197: try {
198: addTextNode("\n");
199: Element temp = (Element) doc.getOwnerDocument().importNode(
200: binding, true);
201: addChildElement((SOAPElement) temp);
202: //(SOAPElement)binding.toElement(doc, MessageConstants.SAML_v1_0_NUMBER));
203: addTextNode("\n");
204: } catch (Exception e) {
205: throw new XWSSecurityException(e);
206: }
207: samlAuthorityBinding = binding;
208: }
209:
210: public Element getSamlAuthorityBinding() {
211: return samlAuthorityBinding;
212: }
213:
214: public void setReference(ReferenceElement referenceElement)
215: throws XWSSecurityException {
216:
217: if (refElement != null) {
218: log.log(Level.SEVERE, "WSS0380.error.setting.reference");
219: throw new XWSSecurityException(
220: "Reference element is already present");
221: }
222:
223: try {
224: addTextNode("\n");
225: addChildElement(referenceElement.getAsSoapElement());
226: addTextNode("\n");
227: } catch (SOAPException e) {
228: log.log(Level.SEVERE, "WSS0381.error.setting.reference");
229: throw new XWSSecurityException(e);
230: }
231:
232: refElement = referenceElement;
233: }
234:
235: public void setWsuId(String wsuId) {
236: setAttributeNS(MessageConstants.NAMESPACES_NS, "xmlns:"
237: + MessageConstants.WSU_PREFIX, MessageConstants.WSU_NS);
238: setAttributeNS(MessageConstants.WSU_NS,
239: MessageConstants.WSU_ID_QNAME, wsuId);
240: }
241:
242: /*
243: * set the WSS 1.1 Token type for SecurityTokenRerference
244: */
245: public void setTokenType(String tokenType) {
246: setAttributeNS(MessageConstants.NAMESPACES_NS, "xmlns:"
247: + MessageConstants.WSSE11_PREFIX,
248: MessageConstants.WSSE11_NS);
249: setAttributeNS(MessageConstants.WSSE11_NS,
250: MessageConstants.WSSE11_TOKEN_TYPE, tokenType);
251: }
252:
253: /*
254: * get the WSS 1.1 Token type for SecurityTokenRerference
255: */
256: public String getTokenType() {
257: return getAttributeNS(MessageConstants.WSSE11_NS, "TokenType");
258: }
259:
260: public static SecurityHeaderBlock fromSoapElement(
261: SOAPElement element) throws XWSSecurityException {
262: return SecurityHeaderBlockImpl.fromSoapElement(element,
263: SecurityTokenReference.class);
264: }
265:
266: /**
267: * Creates an appropriate instance of ReferenceElement depending on the
268: * qualified name of the SOAPElement.
269: */
270: private ReferenceElement getReferenceElementfromSoapElement(
271: SOAPElement element, boolean isBSP)
272: throws XWSSecurityException {
273:
274: String name = element.getLocalName();
275: if (name.equals("KeyIdentifier"))
276: return getKeyIdentifier(element, isBSP);
277: else if (name.equals("Reference"))
278: return new DirectReference(element, isBSP);
279: else if (name.equals("X509Data"))
280: return new X509IssuerSerial(element);
281: else if (isBSP && name.equals("KeyName")) {
282: throw new XWSSecurityException(
283: "Violation of BSP R3027:"
284: + " A SECURITY_TOKEN_REFERENCE MUST NOT use a Key Name to reference a SECURITY_TOKEN."
285: + " KeyName is not supported");
286: } else {
287: log.log(Level.SEVERE, "WSS0335.unsupported.referencetype");
288: XWSSecurityException xwsse = new XWSSecurityException(
289: element.getTagName()
290: + " key reference type is not supported");
291: throw SecurableSoapMessage.newSOAPFaultException(
292: MessageConstants.WSSE_UNSUPPORTED_SECURITY_TOKEN,
293: xwsse.getMessage(), xwsse);
294: }
295: }
296:
297: private KeyIdentifier getKeyIdentifier(SOAPElement element,
298: boolean isBSP) throws XWSSecurityException {
299:
300: String keyIdValueType = element.getAttribute("ValueType");
301: if (isBSP && (keyIdValueType.length() < 1)) {
302: throw new XWSSecurityException(
303: "Voilation of BSP R3054 "
304: + ": A wsse:KeyIdentifier element in a SECURITY_TOKEN_REFERENCE MUST specify a ValueType attribute");
305: }
306:
307: String keyIdEncodingType = element.getAttribute("EncodingType");
308: if (isBSP && (keyIdEncodingType.length() < 1)) {
309: throw new XWSSecurityException(
310: "Voilation of BSP R3070 "
311: + ": A wsse:KeyIdentifier element in a SECURITY_TOKEN_REFERENCE MUST specify an EncodingType attribute. ");
312: }
313:
314: if (isBSP
315: && !(keyIdEncodingType
316: .equals(MessageConstants.BASE64_ENCODING_NS))) {
317: throw new XWSSecurityException(
318: "Voilation of BSP R3071 "
319: + ": An EncodingType attribute on a wsse:KeyIdentifier element in a SECURITY_TOKEN_REFERENCE MUST have a value of http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
320: }
321:
322: if (keyIdValueType
323: .equals(MessageConstants.WSSE_SAML_KEY_IDENTIFIER_VALUE_TYPE)
324: || keyIdValueType
325: .equals(MessageConstants.WSSE_SAML_v2_0_KEY_IDENTIFIER_VALUE_TYPE)) {
326: return new SamlKeyIdentifier(element);
327: } else if ((keyIdValueType
328: .equals(MessageConstants.X509SubjectKeyIdentifier_NS))
329: || (keyIdValueType
330: .equals(MessageConstants.X509v3SubjectKeyIdentifier_NS))) {
331: return new X509SubjectKeyIdentifier(element);
332: } else if ((keyIdValueType
333: .equals(MessageConstants.ThumbPrintIdentifier_NS))) {
334: //TODO: hardcoding as per the current spec status
335: return new X509ThumbPrintIdentifier(element);
336: } else if ((keyIdValueType
337: .equals(MessageConstants.EncryptedKeyIdentifier_NS))) {
338: //TODO: hardcoding as per the current spec status
339: return new EncryptedKeySHA1Identifier(element);
340: } else {
341: log.log(Level.SEVERE, "WSS0334.unsupported.keyidentifier");
342: throw new XWSSecurityException(
343: "Unsupported KeyIdentifier Reference Type encountered");
344: }
345: }
346:
347: public List getAny() {
348: //TODO: Implement this method
349: return null;
350: }
351:
352: public void setId(String value) {
353: setWsuId(value);
354: }
355:
356: public String getType() {
357: //TODO: Implement this method
358: return null;
359: }
360:
361: public Object getTokenValue() {
362: //TODO: Implement this method
363: try {
364: return this .getAsSoapElement();
365: } catch (Exception ex) {
366: throw new RuntimeException(ex);
367: }
368: }
369:
370: }
|