package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml; import java.io.InputStream; import javax.servlet.http.HttpServletRequest; import org.opensaml.core.xml.XMLObject; import org.opensaml.messaging.context.MessageContext; import org.opensaml.messaging.decoder.MessageDecodingException; import org.opensaml.saml.common.SAMLObject; import org.opensaml.saml.common.binding.SAMLBindingSupport; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.saml2.binding.decoding.impl.HTTPRedirectDeflateDecoder; import com.google.common.base.Strings; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SamlHttpUtils; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.primitive.StringSupport; /** * SAML2 Redirect-Binding deflate decoder with same EAAF specific hardening * regarding http request-parameter processing. * * @author tlenz * */ @Slf4j public class EaafHttpRedirectDeflateDecoder extends HTTPRedirectDeflateDecoder { private static final String SAML_REQ_PARAM_NAME = "SAMLRequest"; private static final String SAML_RESP_PARAM_NAME = "SAMLResponse"; public EaafHttpRedirectDeflateDecoder(HttpServletRequest req) { setHttpServletRequest(req); } @Override protected void doDecode() throws MessageDecodingException { final MessageContext messageContext = new MessageContext(); final HttpServletRequest request = getHttpServletRequest(); if (!"GET".equalsIgnoreCase(request.getMethod())) { throw new MessageDecodingException("This message decoder only supports the HTTP GET method"); } final String samlEncoding = StringSupport.trimOrNull(request.getParameter("SAMLEncoding")); if (samlEncoding != null && !SAMLConstants.SAML2_BINDING_URL_ENCODING_DEFLATE_URI.equals(samlEncoding)) { throw new MessageDecodingException("Request indicated an unsupported SAMLEncoding: " + samlEncoding); } final String relayState = request.getParameter("RelayState"); log.debug("Decoded RelayState: {}", relayState); SAMLBindingSupport.setRelayState(messageContext, relayState); final InputStream samlMessageIns; // implement parameter extraction as same as in // SAML2HTTPRedirectDeflateSignatureSecurityHandler.java final String samlReq = SamlHttpUtils.getLastParameterFromRequest(request, SAML_REQ_PARAM_NAME); final String samlResp = SamlHttpUtils.getLastParameterFromRequest(request, SAML_RESP_PARAM_NAME); if (!Strings.isNullOrEmpty(samlReq)) { samlMessageIns = decodeMessage(samlReq); } else if (!Strings.isNullOrEmpty(samlResp)) { samlMessageIns = decodeMessage(samlResp); } else { throw new MessageDecodingException( "No SAMLRequest or SAMLResponse query path parameter, invalid SAML 2 HTTP Redirect message"); } final SAMLObject samlMessage = (SAMLObject) unmarshallMessage(samlMessageIns); messageContext.setMessage(samlMessage); log.debug("Decoded SAML message"); populateBindingContext(messageContext); setMessageContext(messageContext); } /** * EAAF specific unmarshaller perform XML schema validation before unmarshalling * the SAML message. * */ @Override protected XMLObject unmarshallMessage(final InputStream messageStream) throws MessageDecodingException { return Saml2Utils.unmarshallMessage(messageStream); } }