1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.saml2.binding.decoding;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.InputStream;
21 import java.util.zip.Inflater;
22 import java.util.zip.InflaterInputStream;
23
24 import org.opensaml.common.SAMLObject;
25 import org.opensaml.common.binding.SAMLMessageContext;
26 import org.opensaml.common.xml.SAMLConstants;
27 import org.opensaml.ws.message.MessageContext;
28 import org.opensaml.ws.message.decoder.MessageDecodingException;
29 import org.opensaml.ws.transport.http.HTTPInTransport;
30 import org.opensaml.xml.parse.ParserPool;
31 import org.opensaml.xml.util.Base64;
32 import org.opensaml.xml.util.DatatypeHelper;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41 public class HTTPRedirectDeflateDecoder extends BaseSAML2MessageDecoder {
42
43
44 private final Logger log = LoggerFactory.getLogger(HTTPRedirectDeflateDecoder.class);
45
46
47 public HTTPRedirectDeflateDecoder() {
48 super();
49 }
50
51
52
53
54
55
56 public HTTPRedirectDeflateDecoder(ParserPool pool) {
57 super(pool);
58 }
59
60
61 public String getBindingURI() {
62 return SAMLConstants.SAML2_REDIRECT_BINDING_URI;
63 }
64
65
66 protected boolean isIntendedDestinationEndpointURIRequired(SAMLMessageContext samlMsgCtx) {
67 return isMessageSigned(samlMsgCtx);
68 }
69
70
71 protected void doDecode(MessageContext messageContext) throws MessageDecodingException {
72 if (!(messageContext instanceof SAMLMessageContext)) {
73 log.error("Invalid message context type, this decoder only support SAMLMessageContext");
74 throw new MessageDecodingException(
75 "Invalid message context type, this decoder only support SAMLMessageContext");
76 }
77
78 if (!(messageContext.getInboundMessageTransport() instanceof HTTPInTransport)) {
79 log.error("Invalid inbound message transport type, this decoder only support HTTPInTransport");
80 throw new MessageDecodingException(
81 "Invalid inbound message transport type, this decoder only support HTTPInTransport");
82 }
83
84 SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;
85
86 HTTPInTransport inTransport = (HTTPInTransport) samlMsgCtx.getInboundMessageTransport();
87 String relayState = inTransport.getParameterValue("RelayState");
88 samlMsgCtx.setRelayState(relayState);
89 log.debug("Decoded RelayState: {}", relayState);
90
91 InputStream samlMessageIns;
92 if (!DatatypeHelper.isEmpty(inTransport.getParameterValue("SAMLRequest"))) {
93 samlMessageIns = decodeMessage(inTransport.getParameterValue("SAMLRequest"));
94 } else if (!DatatypeHelper.isEmpty(inTransport.getParameterValue("SAMLResponse"))) {
95 samlMessageIns = decodeMessage(inTransport.getParameterValue("SAMLResponse"));
96 } else {
97 throw new MessageDecodingException(
98 "No SAMLRequest or SAMLResponse query path parameter, invalid SAML 2 HTTP Redirect message");
99 }
100
101 SAMLObject samlMessage = (SAMLObject) unmarshallMessage(samlMessageIns);
102 samlMsgCtx.setInboundSAMLMessage(samlMessage);
103 samlMsgCtx.setInboundMessage(samlMessage);
104 log.debug("Decoded SAML message");
105
106 populateMessageContext(samlMsgCtx);
107 }
108
109
110 protected boolean isMessageSigned(SAMLMessageContext messageContext) {
111 HTTPInTransport inTransport = (HTTPInTransport) messageContext.getInboundMessageTransport();
112 String sigParam = inTransport.getParameterValue("Signature");
113 return (!DatatypeHelper.isEmpty(sigParam)) || super.isMessageSigned(messageContext);
114 }
115
116
117
118
119
120
121
122
123
124
125 protected InputStream decodeMessage(String message) throws MessageDecodingException {
126 log.debug("Base64 decoding and inflating SAML message");
127
128 byte[] decodedBytes = Base64.decode(message);
129 if(decodedBytes == null){
130 log.error("Unable to Base64 decode incoming message");
131 throw new MessageDecodingException("Unable to Base64 decode incoming message");
132 }
133
134 try {
135 ByteArrayInputStream bytesIn = new ByteArrayInputStream(decodedBytes);
136 InflaterInputStream inflater = new InflaterInputStream(bytesIn, new Inflater(true));
137 return inflater;
138 } catch (Exception e) {
139 log.error("Unable to Base64 decode and inflate SAML message", e);
140 throw new MessageDecodingException("Unable to Base64 decode and inflate SAML message", e);
141 }
142 }
143 }