
org.opensaml.saml1.binding.decoding.HTTPSOAP11Decoder Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the University Corporation for Advanced Internet Development,
* Inc. (UCAID) under one or more contributor license agreements. See the
* NOTICE file distributed with this work for additional information regarding
* copyright ownership. The UCAID licenses this file to You under the Apache
* License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensaml.saml1.binding.decoding;
import java.util.List;
import javax.xml.namespace.QName;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.binding.SAMLMessageContext;
import org.opensaml.common.binding.artifact.SAMLArtifactMap;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.ws.soap.soap11.Header;
import org.opensaml.ws.transport.http.HTTPInTransport;
import org.opensaml.xml.AttributeExtensibleXMLObject;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.util.DatatypeHelper;
import org.opensaml.xml.util.LazyList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* SAML 1.1 HTTP SOAP 1.1 binding decoder.
*/
public class HTTPSOAP11Decoder extends BaseSAML1MessageDecoder {
/** Class logger. */
private final Logger log = LoggerFactory.getLogger(HTTPSOAP11Decoder.class);
/** QNames of understood SOAP headers. */
private List understoodHeaders;
/** QName of SOAP mustUnderstand header attribute. */
private final QName soapMustUnderstand = new QName(SAMLConstants.SOAP11ENV_NS, "mustUnderstand");
/** Constructor. */
public HTTPSOAP11Decoder() {
super();
understoodHeaders = new LazyList();
}
/**
* Constructor.
*
* @param pool parser pool used to deserialize messages
*/
public HTTPSOAP11Decoder(ParserPool pool) {
super(pool);
understoodHeaders = new LazyList();
}
/**
* Constructor.
*
* @param map Artifact to SAML map
*
* @deprecated
*/
public HTTPSOAP11Decoder(SAMLArtifactMap map) {
super(map);
understoodHeaders = new LazyList();
}
/**
* Constructor.
*
* @param map used to map artifacts to SAML
* @param pool parser pool used to deserialize messages
*
* @deprecated
*/
public HTTPSOAP11Decoder(SAMLArtifactMap map, ParserPool pool) {
super(map, pool);
understoodHeaders = new LazyList();
}
/** {@inheritDoc} */
public String getBindingURI() {
return SAMLConstants.SAML1_SOAP11_BINDING_URI;
}
/**
* Gets the SOAP header names that are understood by the application.
*
* @return SOAP header names that are understood by the application
*/
public List getUnderstoodHeaders() {
return understoodHeaders;
}
/**
* Sets the SOAP header names that are understood by the application.
*
* @param headerNames SOAP header names that are understood by the application
*/
public void setUnderstoodHeaders(List headerNames) {
understoodHeaders.clear();
if (headerNames != null) {
understoodHeaders.addAll(headerNames);
}
}
/** {@inheritDoc} */
protected void doDecode(MessageContext messageContext) throws MessageDecodingException {
if (!(messageContext instanceof SAMLMessageContext)) {
log.error("Invalid message context type, this decoder only support SAMLMessageContext");
throw new MessageDecodingException(
"Invalid message context type, this decoder only support SAMLMessageContext");
}
if (!(messageContext.getInboundMessageTransport() instanceof HTTPInTransport)) {
log.error("Invalid inbound message transport type, this decoder only support HTTPInTransport");
throw new MessageDecodingException(
"Invalid inbound message transport type, this decoder only support HTTPInTransport");
}
SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;
HTTPInTransport inTransport = (HTTPInTransport) samlMsgCtx.getInboundMessageTransport();
if (!inTransport.getHTTPMethod().equalsIgnoreCase("POST")) {
throw new MessageDecodingException("This message decoder only supports the HTTP POST method");
}
log.debug("Unmarshalling SOAP message");
Envelope soapMessage = (Envelope) unmarshallMessage(inTransport.getIncomingStream());
samlMsgCtx.setInboundMessage(soapMessage);
Header messageHeader = soapMessage.getHeader();
if (messageHeader != null) {
checkUnderstoodSOAPHeaders(soapMessage.getHeader().getUnknownXMLObjects());
}
List soapBodyChildren = soapMessage.getBody().getUnknownXMLObjects();
if (soapBodyChildren.size() < 1 || soapBodyChildren.size() > 1) {
log.error("Unexpected number of children in the SOAP body, " + soapBodyChildren.size()
+ ". Unable to extract SAML message");
throw new MessageDecodingException(
"Unexpected number of children in the SOAP body, unable to extract SAML message");
}
XMLObject incommingMessage = soapBodyChildren.get(0);
if (!(incommingMessage instanceof SAMLObject)) {
log.error("Unexpected SOAP body content. Expected a SAML request but recieved {}", incommingMessage
.getElementQName());
throw new MessageDecodingException("Unexpected SOAP body content. Expected a SAML request but recieved "
+ incommingMessage.getElementQName());
}
SAMLObject samlMessage = (SAMLObject) incommingMessage;
log.debug("Decoded SOAP messaged which included SAML message of type {}", samlMessage.getElementQName());
samlMsgCtx.setInboundSAMLMessage(samlMessage);
populateMessageContext(samlMsgCtx);
}
/**
* Checks that, if any SOAP headers, require understand that they are in the understood header list.
*
* @param headers SOAP headers to check
*
* @throws MessageDecodingException thrown if a SOAP header requires understanding but is not understood by the
* decoder
*/
protected void checkUnderstoodSOAPHeaders(List headers) throws MessageDecodingException {
if (headers == null || headers.isEmpty()) {
return;
}
AttributeExtensibleXMLObject attribExtensObject;
for (XMLObject header : headers) {
if (header instanceof AttributeExtensibleXMLObject) {
attribExtensObject = (AttributeExtensibleXMLObject) header;
if (DatatypeHelper.safeEquals("1", attribExtensObject.getUnknownAttributes().get(soapMustUnderstand))) {
if (!understoodHeaders.contains(header.getElementQName())) {
throw new MessageDecodingException("SOAP decoder encountered a header, "
+ header.getElementQName()
+ ", that requires undestanding however this decoder does not understand that header");
}
}
}
}
}
/** {@inheritDoc} */
protected boolean isIntendedDestinationEndpointURIRequired(SAMLMessageContext samlMsgCtx) {
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy