Package org.opensaml.liberty.binding.encoding

Source Code of org.opensaml.liberty.binding.encoding.HTTPPAOS11Encoder

/*
* Copyright 2010 Jonathan Tellier
*
* Licensed 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.liberty.binding.encoding;

import org.opensaml.Configuration;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.SAMLObjectBuilder;
import org.opensaml.common.binding.SAMLMessageContext;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.binding.encoding.BaseSAML2MessageEncoder;
import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder;
import org.opensaml.saml2.ecp.RelayState;
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.ws.soap.common.SOAPObjectBuilder;
import org.opensaml.ws.soap.soap11.Body;
import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.ws.soap.util.SOAPHelper;
import org.opensaml.ws.transport.http.HTTPOutTransport;
import org.opensaml.ws.transport.http.HTTPTransportUtils;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.util.XMLHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

public class HTTPPAOS11Encoder extends BaseSAML2MessageEncoder {

    /**
     * Logger
     */
    private final Logger log = LoggerFactory.getLogger(HTTPSOAP11Encoder.class);

    @Override
    protected void doEncode(MessageContext messageContext) throws MessageEncodingException {

        if (!(messageContext instanceof SAMLMessageContext)) {
            log.error("Invalid message context type, this encoder only support SAMLMessageContext");
            throw new MessageEncodingException(
                    "Invalid message context type, this encoder only support SAMLMessageContext");
        }

        if (!(messageContext.getOutboundMessageTransport() instanceof HTTPOutTransport)) {
            log.error("Invalid outbound message transport type, this encoder only support HTTPOutTransport");
            throw new MessageEncodingException(
                    "Invalid outbound message transport type, this encoder only support HTTPOutTransport");
        }

        // Contains the message body
        SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;
        SAMLObject samlMessage = samlMsgCtx.getOutboundSAMLMessage();
        if (samlMessage == null) {
            throw new MessageEncodingException("No outbound SAML message contained in message context");
        }

        // Add RelayState SOAP header if required
        if (samlMsgCtx.getRelayState() != null) {
            SOAPHelper.addHeaderBlock(samlMsgCtx, getRelayState(samlMsgCtx.getRelayState()));
        }

        signMessage(samlMsgCtx);

        // Contains the entire envelope with any specified headers, but no body
        XMLObject outboundEnveloppe = samlMsgCtx.getOutboundMessage();

        Envelope envelope = buildPAOSMessage(samlMessage, outboundEnveloppe);
        Element envelopeElem = marshallMessage(envelope);

        try {
            HTTPOutTransport outTransport = (HTTPOutTransport) messageContext.getOutboundMessageTransport();
            HTTPTransportUtils.addNoCacheHeaders(outTransport);
            HTTPTransportUtils.setUTF8Encoding(outTransport);
            HTTPTransportUtils.setContentType(outTransport, "text/xml");
            outTransport.setHeader("SOAPAction", "http://www.oasis-open.org/committees/security");
            Writer out = new OutputStreamWriter(outTransport.getOutgoingStream(), "UTF-8");
            XMLHelper.writeNode(envelopeElem, out);
            out.flush();
        } catch (UnsupportedEncodingException e) {
            log.error("JVM does not support required UTF-8 encoding");
            throw new MessageEncodingException("JVM does not support required UTF-8 encoding");
        } catch (IOException e) {
            log.error("Unable to write message content to outbound stream", e);
            throw new MessageEncodingException("Unable to write message content to outbound stream", e);
        }

    }

    /**
     * Method creates a relayState element usable with the ECP profile.
     * @param relayStateValue value to include, mustn't be null
     * @return relay state object
     */
    protected RelayState getRelayState(String relayStateValue) {

        if (relayStateValue == null) {
            throw new IllegalArgumentException("RelayStateValue can't be null");
        }
        if (relayStateValue.length() > 80) {
            throw new IllegalArgumentException("Relay state can't exceed size 80 when using ECP profile");
        }

        XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
        SAMLObjectBuilder<RelayState> relayStateBuilder = (SAMLObjectBuilder<RelayState>) builderFactory.getBuilder(RelayState.DEFAULT_ELEMENT_NAME);
        RelayState relayState = relayStateBuilder.buildObject();
        relayState.setSOAP11Actor(RelayState.SOAP11_ACTOR_NEXT);
        relayState.setSOAP11MustUnderstand(true);
        relayState.setValue(relayStateValue);
        return relayState;

    }

    protected Envelope buildPAOSMessage(SAMLObject samlMessage, XMLObject outboundEnvelope) {

        Envelope envelope;
        XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();

        if (outboundEnvelope != null && outboundEnvelope instanceof Envelope) {
            // We already have a complete envelope with specified headers that we want to keep.
            envelope = (Envelope) outboundEnvelope;
        } else {
            // We don't have an existing envelope, so we create it.
            SOAPObjectBuilder<Envelope> envBuilder = (SOAPObjectBuilder<Envelope>) builderFactory.getBuilder(Envelope.DEFAULT_ELEMENT_NAME);
            envelope = envBuilder.buildObject();
        }

        SOAPObjectBuilder<Body> bodyBuilder = (SOAPObjectBuilder<Body>) builderFactory.getBuilder(Body.DEFAULT_ELEMENT_NAME);
        Body body = bodyBuilder.buildObject();
        body.getUnknownXMLObjects().add(samlMessage);
        envelope.setBody(body);

        return envelope;

    }

    public String getBindingURI() {
        return SAMLConstants.SAML2_PAOS_BINDING_URI;
    }

    public boolean providesMessageConfidentiality(MessageContext messageContext) throws MessageEncodingException {
        return messageContext.getOutboundMessageTransport().isConfidential();
    }

    public boolean providesMessageIntegrity(MessageContext messageContext) throws MessageEncodingException {
        return messageContext.getOutboundMessageTransport().isIntegrityProtected();
    }

}
TOP

Related Classes of org.opensaml.liberty.binding.encoding.HTTPPAOS11Encoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.