1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.saml2.binding.encoding;
18
19 import java.io.IOException;
20 import java.io.OutputStreamWriter;
21 import java.io.UnsupportedEncodingException;
22 import java.io.Writer;
23
24 import org.opensaml.Configuration;
25 import org.opensaml.common.SAMLObject;
26 import org.opensaml.common.binding.SAMLMessageContext;
27 import org.opensaml.common.xml.SAMLConstants;
28 import org.opensaml.ws.message.MessageContext;
29 import org.opensaml.ws.message.encoder.MessageEncodingException;
30 import org.opensaml.ws.soap.common.SOAPObjectBuilder;
31 import org.opensaml.ws.soap.soap11.Body;
32 import org.opensaml.ws.soap.soap11.Envelope;
33 import org.opensaml.ws.transport.http.HTTPOutTransport;
34 import org.opensaml.ws.transport.http.HTTPTransportUtils;
35 import org.opensaml.xml.XMLObjectBuilderFactory;
36 import org.opensaml.xml.util.XMLHelper;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.w3c.dom.Element;
40
41
42
43
44 public class HTTPSOAP11Encoder extends BaseSAML2MessageEncoder {
45
46
47 private final Logger log = LoggerFactory.getLogger(HTTPSOAP11Encoder.class);
48
49
50 public HTTPSOAP11Encoder() {
51 super();
52 }
53
54
55 public String getBindingURI() {
56 return SAMLConstants.SAML2_SOAP11_BINDING_URI;
57 }
58
59
60 public boolean providesMessageConfidentiality(MessageContext messageContext) throws MessageEncodingException {
61 if (messageContext.getOutboundMessageTransport().isConfidential()) {
62 return true;
63 }
64
65 return false;
66 }
67
68
69 public boolean providesMessageIntegrity(MessageContext messageContext) throws MessageEncodingException {
70 if (messageContext.getOutboundMessageTransport().isIntegrityProtected()) {
71 return true;
72 }
73
74 return false;
75 }
76
77
78 protected void doEncode(MessageContext messageContext) throws MessageEncodingException {
79 if (!(messageContext instanceof SAMLMessageContext)) {
80 log.error("Invalid message context type, this encoder only support SAMLMessageContext");
81 throw new MessageEncodingException(
82 "Invalid message context type, this encoder only support SAMLMessageContext");
83 }
84
85 if (!(messageContext.getOutboundMessageTransport() instanceof HTTPOutTransport)) {
86 log.error("Invalid outbound message transport type, this encoder only support HTTPOutTransport");
87 throw new MessageEncodingException(
88 "Invalid outbound message transport type, this encoder only support HTTPOutTransport");
89 }
90
91 SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;
92
93 SAMLObject samlMessage = samlMsgCtx.getOutboundSAMLMessage();
94 if (samlMessage == null) {
95 throw new MessageEncodingException("No outbound SAML message contained in message context");
96 }
97
98 signMessage(samlMsgCtx);
99 Envelope envelope = buildSOAPMessage(samlMessage);
100 samlMsgCtx.setOutboundMessage(envelope);
101
102 Element envelopeElem = marshallMessage(envelope);
103 try {
104 HTTPOutTransport outTransport = (HTTPOutTransport) messageContext.getOutboundMessageTransport();
105 HTTPTransportUtils.addNoCacheHeaders(outTransport);
106 HTTPTransportUtils.setUTF8Encoding(outTransport);
107 HTTPTransportUtils.setContentType(outTransport, "text/xml");
108 outTransport.setHeader("SOAPAction", "http://www.oasis-open.org/committees/security");
109 Writer out = new OutputStreamWriter(outTransport.getOutgoingStream(), "UTF-8");
110 XMLHelper.writeNode(envelopeElem, out);
111 out.flush();
112 } catch (UnsupportedEncodingException e) {
113 log.error("JVM does not support required UTF-8 encoding");
114 throw new MessageEncodingException("JVM does not support required UTF-8 encoding");
115 } catch (IOException e) {
116 log.error("Unable to write message content to outbound stream", e);
117 throw new MessageEncodingException("Unable to write message content to outbound stream", e);
118 }
119 }
120
121
122
123
124
125
126
127
128 @SuppressWarnings("unchecked")
129 protected Envelope buildSOAPMessage(SAMLObject samlMessage) {
130 if (log.isDebugEnabled()) {
131 log.debug("Building SOAP message");
132 }
133 XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
134
135 SOAPObjectBuilder<Envelope> envBuilder = (SOAPObjectBuilder<Envelope>) builderFactory
136 .getBuilder(Envelope.DEFAULT_ELEMENT_NAME);
137 Envelope envelope = envBuilder.buildObject();
138
139 if (log.isDebugEnabled()) {
140 log.debug("Adding SAML message to the SOAP message's body");
141 }
142 SOAPObjectBuilder<Body> bodyBuilder = (SOAPObjectBuilder<Body>) builderFactory
143 .getBuilder(Body.DEFAULT_ELEMENT_NAME);
144 Body body = bodyBuilder.buildObject();
145 body.getUnknownXMLObjects().add(samlMessage);
146 envelope.setBody(body);
147
148 return envelope;
149 }
150 }