/*
* (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* Nelson Silva <nelson.silva@inevo.pt>
*/
package org.nuxeo.ecm.platform.auth.saml.binding;
import org.opensaml.common.binding.decoding.BaseSAMLMessageDecoder;
import org.opensaml.common.binding.decoding.URIComparator;
import org.opensaml.util.SimpleURLCanonicalizer;
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.message.decoder.MessageDecoder;
import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.ws.message.encoder.MessageEncoder;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.ws.transport.InTransport;
import org.opensaml.ws.transport.OutTransport;
/**
* Based class for SAML bindings, used for parsing messages.
*
* @since 6.0
*/
public abstract class SAMLBinding {
protected MessageDecoder decoder;
protected MessageEncoder encoder;
/**
* URIComparator that strips scheme to avoid issues with reverse proxies
*/
public static final URIComparator uriComparator = new URIComparator() {
@Override
public boolean compare(String uri1, String uri2) {
if (uri1 == null && uri2 == null) {
return true;
} else if (uri1 == null || uri2 == null) {
return false;
} else {
String uri1Canon = SimpleURLCanonicalizer.canonicalize(uri1).replaceFirst("^(https:|http:)", "");
String uri2Canon = SimpleURLCanonicalizer.canonicalize(uri2).replaceFirst("^(https:|http:)", "");
return uri1Canon.equals(uri2Canon);
}
}
};
public SAMLBinding(MessageDecoder decoder, MessageEncoder encoder) {
this.decoder = decoder;
this.encoder = encoder;
// NXP-17044: strips scheme to fix validity check with reverse proxies
if (decoder != null) {
((BaseSAMLMessageDecoder) decoder).setURIComparator(uriComparator);
}
}
/**
* Decodes the given message.
*
* @param context the message to decode
* @throws org.opensaml.xml.security.SecurityException
* @throws MessageDecodingException
*/
public void decode(MessageContext context) throws org.opensaml.xml.security.SecurityException,
MessageDecodingException {
decoder.decode(context);
}
/**
* Encodes the given message.
*
* @param context the message to encode
* @throws MessageEncodingException
*/
public void encode(MessageContext context) throws MessageEncodingException {
encoder.encode(context);
}
/**
* Returns the URI that identifies this binding.
*
* @return the URI
*/
public abstract String getBindingURI();
/**
* Checks if this binding can be used to extract the message from the request.
*
* @param transport
* @return true if this binding supports the transport
*/
public abstract boolean supports(InTransport transport);
/**
* Checks if this binding can use the given transport to send a message
*
* @param transport
* @return true if this binding supports the transport
*/
public abstract boolean supports(OutTransport transport);
}