001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nelson Silva <nelson.silva@inevo.pt>
016 */
017package org.nuxeo.ecm.platform.auth.saml.binding;
018
019import org.opensaml.common.SAMLException;
020import org.opensaml.common.binding.SAMLMessageContext;
021import org.opensaml.common.xml.SAMLConstants;
022import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder;
023import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder;
024import org.opensaml.ws.message.encoder.MessageEncodingException;
025import org.opensaml.ws.transport.InTransport;
026import org.opensaml.ws.transport.OutTransport;
027import org.opensaml.ws.transport.http.HTTPInTransport;
028import org.opensaml.ws.transport.http.HTTPOutTransport;
029import org.opensaml.ws.transport.http.HTTPTransport;
030
031/**
032 * HTTP Redirect Binding
033 *
034 * @since 6.0
035 */
036public class HTTPRedirectBinding extends SAMLBinding {
037
038    /**
039     * Extends {@link HTTPRedirectDeflateEncoder} to allow building the redirect URL
040     */
041    private static class DeflateEncoder extends HTTPRedirectDeflateEncoder {
042        public String buildRedirectURL(SAMLMessageContext context, String endpointURL) throws SAMLException {
043            removeSignature(context);
044            try {
045                String encodedMessage = deflateAndBase64Encode(context.getOutboundSAMLMessage());
046                return buildRedirectURL(context, endpointURL, encodedMessage);
047            } catch (MessageEncodingException e) {
048                throw new SAMLException("Failed to build redirect URL", e);
049            }
050        }
051    }
052
053    public static final String SAML_REQUEST = "SAMLRequest";
054
055    public static final String SAML_RESPONSE = "SAMLResponse";
056
057    public HTTPRedirectBinding() {
058        super(new HTTPRedirectDeflateDecoder(), new DeflateEncoder());
059    }
060
061    @Override
062    public String getBindingURI() {
063        return SAMLConstants.SAML2_REDIRECT_BINDING_URI;
064    }
065
066    @Override
067    public boolean supports(InTransport transport) {
068        if (transport instanceof HTTPInTransport) {
069            HTTPTransport t = (HTTPTransport) transport;
070            return "GET".equalsIgnoreCase(t.getHTTPMethod())
071                && (t.getParameterValue(SAML_REQUEST) != null || t.getParameterValue(SAML_RESPONSE) != null);
072        } else {
073            return false;
074        }
075    }
076
077    @Override
078    public boolean supports(OutTransport transport) {
079        return transport instanceof HTTPOutTransport;
080    }
081
082    public String buildRedirectURL(SAMLMessageContext context, String endpointURL) throws SAMLException {
083        return ((DeflateEncoder) encoder).buildRedirectURL(context, endpointURL);
084    }
085}