From e7610325ee2f1d1f4e97e1e7a9b212e692836b5a Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 4 Feb 2020 17:37:34 +0100 Subject: first stable version that uses OpenSAML 3.x --- .../modules/pvp2/impl/binding/SoapBinding.java | 104 ++++++++++----------- 1 file changed, 48 insertions(+), 56 deletions(-) (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java') diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java index e0df2d2a..49e93f0a 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java @@ -21,6 +21,7 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.binding; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; @@ -29,27 +30,29 @@ import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.exception.AttributQueryException; +import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidPvpRequestException; import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException; import at.gv.egiz.eaaf.modules.pvp2.exception.SamlBindingException; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import at.gv.egiz.eaaf.modules.pvp2.impl.verification.EaafMessageContextInitializationHandler; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.EaafSamlProtocolMessageXmlSignatureSecurityHandler; import at.gv.egiz.eaaf.modules.pvp2.impl.verification.PvpSamlMessageHandlerChain; 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.binding.impl.CheckMessageVersionHandler; import org.opensaml.saml.common.binding.impl.SAMLProtocolAndRoleHandler; import org.opensaml.saml.common.binding.impl.SAMLSOAPDecoderBodyHandler; import org.opensaml.saml.common.binding.security.impl.MessageLifetimeSecurityHandler; -import org.opensaml.saml.common.binding.security.impl.SAMLProtocolMessageXMLSignatureSecurityHandler; import org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.saml2.binding.decoding.impl.HTTPSOAP11Decoder; import org.opensaml.saml.saml2.binding.encoding.impl.HTTPSOAP11Encoder; import org.opensaml.saml.saml2.core.RequestAbstractType; import org.opensaml.saml.saml2.core.StatusResponseType; +import org.opensaml.soap.messaging.context.SOAP11Context; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; @@ -61,72 +64,55 @@ public class SoapBinding extends AbstractBinding implements IDecoder, IEncoder { @Override public InboundMessageInterface decode(final HttpServletRequest req, final HttpServletResponse resp, final IPvp2MetadataProvider metadataProvider, - final boolean isSpEndPoint, final URIComparator comparator) + QName peerEntityRole, final URIComparator comparator) throws Pvp2Exception { - try { - final HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(); + final HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(); + soapDecoder.setHttpServletRequest(req); + + injectMessageHandlerChain(soapDecoder, metadataProvider, peerEntityRole); + + final MessageContext messageContext = + internalMessageDecode(soapDecoder, PvpConstants.SOAP); + + // check if PVP2 AuthnRequest is signed + if (!SAMLBindingSupport.isMessageSigned(messageContext)) { + log.info("SAML Post-Binding message contains no signature. Message will be rejected"); + throw new InvalidPvpRequestException("internal.pvp.02", null); + + } + + return performMessageDecodePostProcessing(messageContext, true); + } + private void injectMessageHandlerChain(HTTPSOAP11Decoder soapDecoder, + IPvp2MetadataProvider metadataProvider, QName peerEntityRole) throws Pvp2InternalErrorException { + try { final PvpSamlMessageHandlerChain messageValidatorChain = new PvpSamlMessageHandlerChain(); - soapDecoder.setBodyHandler(messageValidatorChain); + messageValidatorChain.addHandler(new EaafMessageContextInitializationHandler(metadataProvider)); + messageValidatorChain.addHandler(new SAMLSOAPDecoderBodyHandler()); - final SAMLProtocolMessageXMLSignatureSecurityHandler msgSignatureValidationHandler = - new SAMLProtocolMessageXMLSignatureSecurityHandler(); + final SAMLProtocolAndRoleHandler samlProtocolHandler = new SAMLProtocolAndRoleHandler(); + samlProtocolHandler.setProtocol(SAMLConstants.SAML20P_NS); + samlProtocolHandler.setRole(peerEntityRole); + messageValidatorChain.addHandler(samlProtocolHandler); - messageValidatorChain.addHandler(new EaafMessageContextInitializationHandler()); messageValidatorChain.addHandler(new CheckMessageVersionHandler()); - messageValidatorChain.addHandler(new SAMLProtocolAndRoleHandler()); - messageValidatorChain.addHandler(msgSignatureValidationHandler); + messageValidatorChain.addHandler( + new EaafSamlProtocolMessageXmlSignatureSecurityHandler(metadataProvider)); messageValidatorChain.addHandler(new MessageLifetimeSecurityHandler()); - messageValidatorChain.addHandler(new SAMLSOAPDecoderBodyHandler()); - // decode message - soapDecoder.initialize(); - soapDecoder.decode(); + messageValidatorChain.initialize(); - final MessageContext messageContext = soapDecoder.getMessageContext(); - messageContext.getMessage(); + soapDecoder.setBodyHandler(messageValidatorChain); + + } catch (final ComponentInitializationException e) { + log.warn("Internal initialization error. Reason: {}", e.getMessage()); + throw new Pvp2InternalErrorException(e); - } catch (MessageDecodingException | ComponentInitializationException e) { - throw new SamlBindingException("internal.pvp.95", - new Object[] { PvpConstants.POST, "decoding", e.getMessage() }, - e); } -// final Envelope inboundMessage = (Envelope) messageContext.getMessage(); -// -// if (inboundMessage.getBody() != null) { -// final List xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); -// -// if (!xmlElemList.isEmpty()) { -// final SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); -// final PvpSProfileRequest request = new PvpSProfileRequest(attrReq, getSaml2BindingName()); -// -// if (messageContext.getPeerEntityMetadata() != null) { -// request.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); -// -// } else if (attrReq instanceof RequestAbstractType) { -// final RequestAbstractType attributeRequest = (RequestAbstractType) attrReq; -// try { -// if (StringUtils.isNotEmpty(attributeRequest.getIssuer().getValue()) -// && metadataProvider.getRole(attributeRequest.getIssuer().getValue(), -// SPSSODescriptor.DEFAULT_ELEMENT_NAME) != null) { -// request.setEntityID(attributeRequest.getIssuer().getValue()); -// } -// -// } catch (final Exception e) { -// log.warn("No Metadata found with EntityID " + attributeRequest.getIssuer().getValue()); -// } -// } -// -// request.setVerified(false); -// return request; -// -// } -// } - - log.error("Receive empty PVP 2.1 attributequery request."); - throw new AttributQueryException("Receive empty PVP 2.1 attributequery request.", null); + } @Override @@ -157,6 +143,11 @@ public class SoapBinding extends AbstractBinding implements IDecoder, IEncoder { // inject message context final MessageContext messageContext = buildBasicMessageContext(encoder, response); + //inject SOAP enveloped + final SOAP11Context soap11Context = new SOAP11Context(); + soap11Context.setEnvelope(Saml2Utils.buildSoap11Envelope(response)); + messageContext.addSubcontext(soap11Context); + // inject signing context messageContext.addSubcontext(injectSigningInfos(credentials)); @@ -172,6 +163,7 @@ public class SoapBinding extends AbstractBinding implements IDecoder, IEncoder { // encode message encoder.initialize(); encoder.encode(); + } catch (final Exception e) { log.warn("Can not encode SAML2 SOAP-Binding response", e); throw new SamlBindingException("internal.pvp.95", -- cgit v1.2.3