001/* 002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nelson Silva <[email protected]> 018 */ 019package org.nuxeo.ecm.platform.auth.saml.binding; 020 021import org.opensaml.common.binding.decoding.BaseSAMLMessageDecoder; 022import org.opensaml.common.binding.decoding.URIComparator; 023import org.opensaml.util.SimpleURLCanonicalizer; 024import org.opensaml.ws.message.MessageContext; 025import org.opensaml.ws.message.decoder.MessageDecoder; 026import org.opensaml.ws.message.decoder.MessageDecodingException; 027import org.opensaml.ws.message.encoder.MessageEncoder; 028import org.opensaml.ws.message.encoder.MessageEncodingException; 029import org.opensaml.ws.transport.InTransport; 030import org.opensaml.ws.transport.OutTransport; 031 032/** 033 * Based class for SAML bindings, used for parsing messages. 034 * 035 * @since 6.0 036 */ 037public abstract class SAMLBinding { 038 039 protected MessageDecoder decoder; 040 041 protected MessageEncoder encoder; 042 043 /** 044 * URIComparator that strips scheme to avoid issues with reverse proxies 045 */ 046 public static final URIComparator uriComparator = new URIComparator() { 047 @Override 048 public boolean compare(String uri1, String uri2) { 049 if (uri1 == null && uri2 == null) { 050 return true; 051 } else if (uri1 == null || uri2 == null) { 052 return false; 053 } else { 054 String uri1Canon = SimpleURLCanonicalizer.canonicalize(uri1).replaceFirst("^(https:|http:)", ""); 055 String uri2Canon = SimpleURLCanonicalizer.canonicalize(uri2).replaceFirst("^(https:|http:)", ""); 056 return uri1Canon.equals(uri2Canon); 057 } 058 } 059 }; 060 061 public SAMLBinding(MessageDecoder decoder, MessageEncoder encoder) { 062 this.decoder = decoder; 063 this.encoder = encoder; 064 // NXP-17044: strips scheme to fix validity check with reverse proxies 065 if (decoder != null) { 066 ((BaseSAMLMessageDecoder) decoder).setURIComparator(uriComparator); 067 } 068 } 069 070 /** 071 * Decodes the given message. 072 * 073 * @param context the message to decode 074 * @throws org.opensaml.xml.security.SecurityException 075 * @throws MessageDecodingException 076 */ 077 public void decode(MessageContext context) throws org.opensaml.xml.security.SecurityException, 078 MessageDecodingException { 079 decoder.decode(context); 080 } 081 082 /** 083 * Encodes the given message. 084 * 085 * @param context the message to encode 086 * @throws MessageEncodingException 087 */ 088 public void encode(MessageContext context) throws MessageEncodingException { 089 encoder.encode(context); 090 } 091 092 /** 093 * Returns the URI that identifies this binding. 094 * 095 * @return the URI 096 */ 097 public abstract String getBindingURI(); 098 099 /** 100 * Checks if this binding can be used to extract the message from the request. 101 * 102 * @param transport 103 * @return true if this binding supports the transport 104 */ 105 public abstract boolean supports(InTransport transport); 106 107 /** 108 * Checks if this binding can use the given transport to send a message 109 * 110 * @param transport 111 * @return true if this binding supports the transport 112 */ 113 public abstract boolean supports(OutTransport transport); 114}