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.binding.decoding.BaseSAMLMessageDecoder; 020import org.opensaml.common.binding.decoding.URIComparator; 021import org.opensaml.util.SimpleURLCanonicalizer; 022import org.opensaml.ws.message.MessageContext; 023import org.opensaml.ws.message.decoder.MessageDecoder; 024import org.opensaml.ws.message.decoder.MessageDecodingException; 025import org.opensaml.ws.message.encoder.MessageEncoder; 026import org.opensaml.ws.message.encoder.MessageEncodingException; 027import org.opensaml.ws.transport.InTransport; 028import org.opensaml.ws.transport.OutTransport; 029 030/** 031 * Based class for SAML bindings, used for parsing messages. 032 * 033 * @since 6.0 034 */ 035public abstract class SAMLBinding { 036 037 protected MessageDecoder decoder; 038 039 protected MessageEncoder encoder; 040 041 /** 042 * URIComparator that strips scheme to avoid issues with reverse proxies 043 */ 044 public static final URIComparator uriComparator = new URIComparator() { 045 @Override 046 public boolean compare(String uri1, String uri2) { 047 if (uri1 == null && uri2 == null) { 048 return true; 049 } else if (uri1 == null || uri2 == null) { 050 return false; 051 } else { 052 String uri1Canon = SimpleURLCanonicalizer.canonicalize(uri1).replaceFirst("^(https:|http:)", ""); 053 String uri2Canon = SimpleURLCanonicalizer.canonicalize(uri2).replaceFirst("^(https:|http:)", ""); 054 return uri1Canon.equals(uri2Canon); 055 } 056 } 057 }; 058 059 public SAMLBinding(MessageDecoder decoder, MessageEncoder encoder) { 060 this.decoder = decoder; 061 this.encoder = encoder; 062 // NXP-17044: strips scheme to fix validity check with reverse proxies 063 if (decoder != null) { 064 ((BaseSAMLMessageDecoder) decoder).setURIComparator(uriComparator); 065 } 066 } 067 068 /** 069 * Decodes the given message. 070 * 071 * @param context the message to decode 072 * @throws org.opensaml.xml.security.SecurityException 073 * @throws MessageDecodingException 074 */ 075 public void decode(MessageContext context) throws org.opensaml.xml.security.SecurityException, 076 MessageDecodingException { 077 decoder.decode(context); 078 } 079 080 /** 081 * Encodes the given message. 082 * 083 * @param context the message to encode 084 * @throws MessageEncodingException 085 */ 086 public void encode(MessageContext context) throws MessageEncodingException { 087 encoder.encode(context); 088 } 089 090 /** 091 * Returns the URI that identifies this binding. 092 * 093 * @return the URI 094 */ 095 public abstract String getBindingURI(); 096 097 /** 098 * Checks if this binding can be used to extract the message from the request. 099 * 100 * @param transport 101 * @return true if this binding supports the transport 102 */ 103 public abstract boolean supports(InTransport transport); 104 105 /** 106 * Checks if this binding can use the given transport to send a message 107 * 108 * @param transport 109 * @return true if this binding supports the transport 110 */ 111 public abstract boolean supports(OutTransport transport); 112}