001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the License). You may not use this file except in
005: * compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * Header Notice in each file and include the License file
014: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * If applicable, add the following below the CDDL Header,
016: * with the fields enclosed by brackets [] replaced by
017: * you own identifying information:
018: * "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
021: */
022:
023: package com.sun.xml.ws.security.opt.impl.incoming;
024:
025: import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
026: import com.sun.xml.stream.buffer.stax.StreamReaderBufferCreator;
027: import com.sun.xml.stream.buffer.stax.StreamWriterBufferCreator;
028: import com.sun.xml.ws.security.opt.api.NamespaceContextInfo;
029: import com.sun.xml.ws.security.opt.api.PolicyBuilder;
030: import com.sun.xml.ws.security.opt.api.SecurityElementWriter;
031: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
032: import com.sun.xml.ws.security.opt.api.TokenValidator;
033: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
034: import com.sun.xml.ws.security.opt.impl.incoming.processor.KeyInfoProcessor;
035: import com.sun.xml.ws.security.opt.impl.util.StreamUtil;
036: import com.sun.xml.wss.ProcessingContext;
037: import com.sun.xml.wss.XWSSecurityException;
038: import com.sun.xml.wss.impl.MessageConstants;
039:
040: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
041: import java.io.OutputStream;
042: import java.security.Key;
043: import java.util.HashMap;
044: import javax.xml.crypto.KeySelector.Purpose;
045: import javax.xml.stream.XMLStreamException;
046: import javax.xml.stream.XMLStreamReader;
047: import javax.xml.stream.XMLStreamWriter;
048: import static com.sun.xml.wss.impl.MessageConstants.SIGNATURE_LNAME;
049: import static com.sun.xml.wss.impl.MessageConstants.DSIG_NS;
050: import com.sun.xml.wss.saml.Assertion;
051: import com.sun.xml.wss.saml.SAMLException;
052: import java.util.logging.Level;
053: import javax.security.auth.Subject;
054: import javax.xml.parsers.DocumentBuilder;
055: import javax.xml.parsers.DocumentBuilderFactory;
056: import javax.xml.stream.XMLOutputFactory;
057: import javax.xml.transform.dom.DOMResult;
058: import org.w3c.dom.Document;
059: import org.w3c.dom.Element;
060: import org.w3c.dom.NodeList;
061:
062: /**
063: *
064: * @author K.Venugopal@sun.com
065: */
066: public class SAMLAssertion implements SecurityHeaderElement,
067: PolicyBuilder, TokenValidator, NamespaceContextInfo,
068: SecurityElementWriter {
069:
070: private String id = "";
071: private String localName = "";
072: private String namespaceURI = "";
073: private Key key = null;
074: private JAXBFilterProcessingContext jpc = null;
075: private HashMap<String, String> samlHeaderNSContext = null;
076: private StreamReaderBufferCreator creator = null;
077: private Signature sig = null;
078: private MutableXMLStreamBuffer buffer = null;
079:
080: private static final String KEYINFO_ELEMENT = "KeyInfo";
081:
082: /** Creates a new instance of SAMLAssertion */
083: public SAMLAssertion(XMLStreamReader reader,
084: JAXBFilterProcessingContext jpc,
085: StreamReaderBufferCreator creator, HashMap nsDecl)
086: throws XWSSecurityException {
087: this .jpc = jpc;
088: this .creator = creator;
089: id = reader.getAttributeValue(null, "AssertionID");
090: if (id == null) {
091: id = reader.getAttributeValue(null, "ID");
092: }
093: namespaceURI = reader.getNamespaceURI();
094: localName = reader.getLocalName();
095: samlHeaderNSContext = new HashMap<String, String>();
096: samlHeaderNSContext.putAll(nsDecl);
097: if (reader.getNamespaceCount() > 0) {
098: for (int i = 0; i < reader.getNamespaceCount(); i++) {
099: samlHeaderNSContext.put(reader.getNamespacePrefix(i),
100: reader.getNamespaceURI(i));
101: }
102: }
103:
104: //to be picked up from pool of buffers.
105: buffer = new MutableXMLStreamBuffer();
106: StreamWriterBufferCreator bCreator = new StreamWriterBufferCreator(
107: buffer);
108: process(reader, (XMLStreamWriter) bCreator);
109: }
110:
111: public SAMLAssertion() {
112: }
113:
114: public boolean refersToSecHdrWithId(String id) {
115: return false;
116: }
117:
118: public String getId() {
119: return id;
120: }
121:
122: public void setId(final String id) {
123: throw new UnsupportedOperationException("not implemented");
124: }
125:
126: public String getNamespaceURI() {
127: return namespaceURI;
128: }
129:
130: public String getLocalPart() {
131: return localName;
132: }
133:
134: public XMLStreamReader readHeader() throws XMLStreamException {
135: return buffer.readAsXMLStreamReader();
136: }
137:
138: public WSSPolicy getPolicy() {
139: return null;
140: }
141:
142: public void validate(ProcessingContext context)
143: throws XWSSecurityException {
144: try {
145: context.getSecurityEnvironment().validateSAMLAssertion(
146: context.getExtraneousProperties(), readHeader());
147: context.getSecurityEnvironment().updateOtherPartySubject(
148: (Subject) context.getExtraneousProperties().get(
149: MessageConstants.AUTH_SUBJECT),
150: readHeader());
151: } catch (XMLStreamException xe) {
152: throw new XWSSecurityException(
153: "Error occurred while trying to validate SAMLAssertion",
154: xe);
155: }
156: }
157:
158: public HashMap<String, String> getInscopeNSContext() {
159: return samlHeaderNSContext;
160: }
161:
162: public void writeTo(XMLStreamWriter streamWriter)
163: throws XMLStreamException {
164: buffer.writeToXMLStreamWriter(streamWriter);
165: }
166:
167: public void writeTo(XMLStreamWriter streamWriter, HashMap props)
168: throws XMLStreamException {
169: //is this ok?
170: writeTo(streamWriter);
171: }
172:
173: public void writeTo(OutputStream os) {
174: throw new UnsupportedOperationException();
175: }
176:
177: public boolean isHOK() {
178: if (sig != null) {
179: return true;
180: }
181: return false;
182: }
183:
184: public boolean validateSignature() throws XWSSecurityException {
185: if (isHOK()) {
186: return sig.validate();
187: }
188: return false;
189: }
190:
191: public void processNoValidation(XMLStreamReader reader,
192: XMLStreamWriter buffer) throws XWSSecurityException {
193:
194: try {
195: StreamUtil.writeCurrentEvent(reader, buffer);
196: while (reader.hasNext()) {
197: reader.next();
198: if (_break(reader)) {
199: StreamUtil.writeCurrentEvent(reader, buffer);
200: reader.next();
201: break;
202: } else {
203: StreamUtil.writeCurrentEvent(reader, buffer);
204: }
205: }
206: } catch (XMLStreamException xe) {
207: throw new XWSSecurityException(
208: "Error occurred while reading SAMLAssertion", xe);
209: }
210: }
211:
212: public void process(XMLStreamReader reader, XMLStreamWriter buffer)
213: throws XWSSecurityException {
214:
215: try {
216: StreamUtil.writeCurrentEvent(reader, buffer);
217: while (reader.hasNext()) {
218: reader.next();
219: switch (reader.getEventType()) {
220: case XMLStreamReader.START_ELEMENT: {
221: if (reader.getLocalName() == SIGNATURE_LNAME
222: && reader.getNamespaceURI() == DSIG_NS) {
223: sig = new Signature(jpc, samlHeaderNSContext,
224: creator, false);
225: sig.process(reader, false);
226: }
227: break;
228: }
229: }
230: if (_break(reader)) {
231: StreamUtil.writeCurrentEvent(reader, buffer);
232: reader.next();
233: break;
234: } else {
235: StreamUtil.writeCurrentEvent(reader, buffer);
236: }
237: }
238: } catch (XMLStreamException xe) {
239: throw new XWSSecurityException(
240: "Error occurred while reading SAMLAssertion", xe);
241: }
242: }
243:
244: public Key getKey() throws XWSSecurityException {
245: if (key == null) {
246: try {
247: XMLStreamReader reader = readHeader();
248: while (reader.getEventType() != reader.END_DOCUMENT) {
249: switch (reader.getEventType()) {
250: case XMLStreamReader.START_ELEMENT: {
251: if (reader.getLocalName() == KEYINFO_ELEMENT
252: && reader.getNamespaceURI() == DSIG_NS) {
253: jpc.isSAMLEK(true);
254: KeyInfoProcessor kip = new KeyInfoProcessor(
255: jpc, Purpose.VERIFY);
256: key = kip.getKey(reader);
257: jpc.isSAMLEK(false);
258: return key;
259: }
260: break;
261: }
262: default: {
263: break;
264: }
265: }
266: if (reader.hasNext()) {
267: reader.next();
268: } else {
269: break;//should not happen;
270: }
271: }
272: } catch (XMLStreamException xe) {
273: throw new XWSSecurityException(
274: "Error occurred while obtaining Key from SAMLAssertion",
275: xe);
276: }
277: }
278: return key;
279: }
280:
281: private boolean _break(XMLStreamReader reader) {
282: if (reader.getEventType() == reader.END_ELEMENT) {
283: if (reader.getLocalName() == MessageConstants.SAML_ASSERTION_LNAME) {
284: String uri = reader.getNamespaceURI();
285: if (uri == MessageConstants.SAML_v2_0_NS
286: || uri == MessageConstants.SAML_v1_0_NS
287: || uri == MessageConstants.SAML_v1_1_NS) {
288: return true;
289: }
290: }
291: }
292: return false;
293: }
294:
295: }
|