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/AbstractBinding.java | 127 +++++++++++++++++++-- 1 file changed, 119 insertions(+), 8 deletions(-) (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/AbstractBinding.java') diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/AbstractBinding.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/AbstractBinding.java index ae108c35..3543d85a 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/AbstractBinding.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/AbstractBinding.java @@ -1,15 +1,29 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.binding; +import javax.xml.namespace.QName; + import at.gv.egiz.eaaf.core.api.idp.IConfiguration; 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.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.exception.SamlMessageValidationException; import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.PvpSamlMessageHandlerChain; import org.opensaml.core.config.ConfigurationService; import org.opensaml.messaging.context.BaseContext; import org.opensaml.messaging.context.MessageContext; +import org.opensaml.messaging.decoder.MessageDecodingException; +import org.opensaml.messaging.decoder.servlet.HttpServletRequestMessageDecoder; +import org.opensaml.messaging.handler.MessageHandlerException; import org.opensaml.saml.common.SAMLObject; import org.opensaml.saml.common.SignableSAMLObject; import org.opensaml.saml.common.binding.SAMLBindingSupport; @@ -19,6 +33,8 @@ import org.opensaml.saml.common.messaging.context.SAMLMessageInfoContext; import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext; import org.opensaml.saml.common.messaging.context.SAMLProtocolContext; import org.opensaml.saml.common.xml.SAMLConstants; +import org.opensaml.saml.saml2.core.RequestAbstractType; +import org.opensaml.saml.saml2.core.StatusResponseType; import org.opensaml.saml.saml2.metadata.SingleSignOnService; import org.opensaml.saml.saml2.metadata.impl.SingleSignOnServiceBuilder; import org.opensaml.xmlsec.SignatureSigningParameters; @@ -28,21 +44,62 @@ import org.opensaml.xmlsec.context.SecurityParametersContext; import org.opensaml.xmlsec.signature.support.SignatureConstants; import org.springframework.beans.factory.annotation.Autowired; +import com.google.common.base.Optional; +import com.google.common.base.Predicates; +import com.google.common.base.Throwables; +import com.google.common.collect.FluentIterable; +import lombok.extern.slf4j.Slf4j; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; + /** * Abstract Binding implements common code for SAML2 binding implementations. * * @author tlenz * */ +@Slf4j public abstract class AbstractBinding { - @Autowired protected IConfiguration basicConfig; + @Autowired + protected IConfiguration basicConfig; public abstract String getSaml2BindingName(); + protected MessageContext internalMessageDecode( + HttpServletRequestMessageDecoder decoder, + String binding) throws Pvp2Exception { + try { + decoder.initialize(); + decoder.decode(); + + } catch (final ComponentInitializationException e) { + log.warn("Internal initialization error. Reason: {}", e.getMessage()); + throw new Pvp2InternalErrorException(e); + + } catch (final MessageDecodingException e) { + final Optional pvpException = FluentIterable.from( + Throwables.getCausalChain(e)).filter( + Predicates.instanceOf(Pvp2Exception.class)).first(); + + if (pvpException.isPresent()) { + throw (Pvp2Exception) pvpException.get(); + + } else { + throw new SamlBindingException("internal.pvp.95", + new Object[] { binding, "decoding", e.getMessage() }, + e); + + } + + } + + return decoder.getMessageContext(); + + } + protected MessageContext buildBasicMessageContext( SAMLMessageEncoder encoder, SignableSAMLObject response) { - final MessageContext messageContext = new MessageContext(); + final MessageContext messageContext = new MessageContext<>(); messageContext.setMessage(response); encoder.setMessageContext(messageContext); return messageContext; @@ -63,7 +120,7 @@ public abstract class AbstractBinding { signingParams.setSignatureReferenceDigestMethod( Saml2Utils.getDigestAlgorithm(signingParams.getSignatureAlgorithm())); - signingParams.setKeyInfoGenerator(Saml2Utils.getKeyInfoGenerator(credentials, false)); + signingParams.setKeyInfoGenerator(Saml2Utils.getKeyInfoGenerator(credentials, true)); return securityParamContext; @@ -83,16 +140,16 @@ public abstract class AbstractBinding { } protected void injectInboundMessageContexts(MessageContext messageContext, - IPvp2MetadataProvider metadataProvider) { - messageContext.addSubcontext(new SAMLPeerEntityContext()); + IPvp2MetadataProvider metadataProvider, QName peerEntityRole) throws Pvp2InternalErrorException { + final SAMLPeerEntityContext peerEntityContext = new SAMLPeerEntityContext(); + peerEntityContext.setRole(peerEntityRole); + messageContext.addSubcontext(peerEntityContext); messageContext.addSubcontext(new SAMLMessageInfoContext()); - final SAMLProtocolContext protocolContext = new SAMLProtocolContext(); protocolContext.setProtocol(SAMLConstants.SAML20P_NS); messageContext.addSubcontext(protocolContext); - final SecurityParametersContext securityParameterContext = new SecurityParametersContext(); final SignatureValidationParameters sigValParameters = new SignatureValidationParameters(); securityParameterContext.setSignatureValidationParameters(sigValParameters); @@ -100,9 +157,63 @@ public abstract class AbstractBinding { sigValParameters.setBlacklistedAlgorithms( ConfigurationService.get(SignatureValidationConfiguration.class) - .getBlacklistedAlgorithms()); + .getBlacklistedAlgorithms()); sigValParameters.setSignatureTrustEngine( TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); } + + protected void performMessageValidation(PvpSamlMessageHandlerChain messageValidatorChain, + MessageContext messageContext) throws Pvp2Exception { + try { + messageValidatorChain.initialize(); + messageValidatorChain.invoke(messageContext); + + } catch (final ComponentInitializationException e) { + log.warn("Internal initialization error. Reason: {}", e.getMessage()); + throw new Pvp2InternalErrorException(e); + + } catch (final MessageHandlerException e) { + log.info("SAML message validation error. Reason: {}", e.getMessage()); + final Optional pvpException = FluentIterable.from( + Throwables.getCausalChain(e)).filter( + Predicates.instanceOf(Pvp2Exception.class)).first(); + + if (pvpException.isPresent()) { + throw (Pvp2Exception) pvpException.get(); + + } else { + throw new SamlMessageValidationException("internal.pvp.11", + new Object[] { e.getMessage() }, e); + + } + } + } + + protected InboundMessageInterface performMessageDecodePostProcessing( + MessageContext messageContext, boolean isVerified) { + InboundMessage msg = null; + if (messageContext.getMessage() instanceof RequestAbstractType) { + final RequestAbstractType inboundMessage = + (RequestAbstractType) messageContext.getMessage(); + msg = new PvpSProfileRequest(inboundMessage, getSaml2BindingName()); + msg.setEntityID(inboundMessage.getIssuer().getValue()); + + } else if (messageContext.getMessage() instanceof StatusResponseType) { + final StatusResponseType inboundMessage = + (StatusResponseType) messageContext.getMessage(); + msg = new PvpSProfileResponse(inboundMessage); + msg.setEntityID(inboundMessage.getIssuer().getValue()); + + } else { + // create empty container if request type is unknown + msg = new InboundMessage(); + + } + + msg.setVerified(isVerified); + msg.setRelayState(SAMLBindingSupport.getRelayState(messageContext)); + + return msg; + } } -- cgit v1.2.3