summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-02-04 17:37:34 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-02-04 17:37:34 +0100
commite7610325ee2f1d1f4e97e1e7a9b212e692836b5a (patch)
treeed7c0dba5fed47e80e68b4ab5a63846c5724a8e7 /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java
parent41ea2fdf782cd64d7d29f73c2e83f9c255810818 (diff)
downloadEAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.tar.gz
EAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.tar.bz2
EAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.zip
first stable version that uses OpenSAML 3.x
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java147
1 files changed, 73 insertions, 74 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java
index 6f39392d..c679de20 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.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.core.api.gui.IGuiBuilderConfigurationFactory;
@@ -36,16 +37,17 @@ import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
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.SamlBindingException;
-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.opensaml.EaafHttpPostDecoder;
import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.HttpPostEncoderWithOwnTemplate;
+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.security.impl.MessageLifetimeSecurityHandler;
+import org.opensaml.saml.common.binding.security.impl.ReceivedEndpointSecurityHandler;
import org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.saml2.core.RequestAbstractType;
@@ -53,7 +55,6 @@ import org.opensaml.saml.saml2.core.StatusResponseType;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.net.URIComparator;
@Slf4j
@@ -78,35 +79,34 @@ public class PostBinding extends AbstractBinding implements IDecoder, IEncoder {
guiConfigFactory.getSpSpecificSaml2PostConfiguration(pendingReq,
"pvp_postbinding_template.html", authConfig.getConfigurationRootDirectory());
- final HttpPostEncoderWithOwnTemplate encoder
- = new HttpPostEncoderWithOwnTemplate(guiConfig, guiBuilder);
+ final HttpPostEncoderWithOwnTemplate encoder = new HttpPostEncoderWithOwnTemplate(guiConfig,
+ guiBuilder);
encoder.setHttpServletResponse(httpResp);
- //inject message context
+ // inject message context
final MessageContext<SAMLObject> messageContext = buildBasicMessageContext(encoder, request);
- //inject signing context
+ // inject signing context
messageContext.addSubcontext(injectSigningInfos(credentials));
- //set endpoint url
+ // set endpoint url
messageContext.addSubcontext(injectEndpointInfos(request, targetLocation));
-
- //set relayState of exists
+ // set relayState of exists
SAMLBindingSupport.setRelayState(messageContext, relayState);
- //sign SAML2 message
+ // sign SAML2 message
SAMLMessageSecuritySupport.signMessage(messageContext);
- //encode message
+ // encode message
encoder.initialize();
encoder.encode();
} catch (final Exception e) {
log.warn("Can not encode SAML2 Post-Binding request", e);
throw new SamlBindingException("internal.pvp.95",
- new Object[] {PvpConstants.POST, "encoding", e.getMessage()},
+ new Object[] { PvpConstants.POST, "encoding", e.getMessage() },
e);
}
@@ -116,7 +116,7 @@ public class PostBinding extends AbstractBinding implements IDecoder, IEncoder {
public void encodeResponse(final HttpServletRequest httpReq, final HttpServletResponse httpResp,
final StatusResponseType response, final String targetLocation, final String relayState,
final EaafX509Credential credentials, final IRequest pendingReq)
- throws Pvp2Exception {
+ throws Pvp2Exception {
try {
log.debug("create SAML POSTBinding response");
@@ -130,99 +130,62 @@ public class PostBinding extends AbstractBinding implements IDecoder, IEncoder {
encoder.setHttpServletResponse(httpResp);
- //inject message context
+ // inject message context
final MessageContext<SAMLObject> messageContext = buildBasicMessageContext(encoder, response);
- //inject signing context
+ // inject signing context
messageContext.addSubcontext(injectSigningInfos(credentials));
- //set endpoint url
+ // set endpoint url
messageContext.addSubcontext(injectEndpointInfos(response, targetLocation));
- //set relayState of exists
+ // set relayState of exists
SAMLBindingSupport.setRelayState(messageContext, relayState);
- //sign SAML2 message
+ // sign SAML2 message
SAMLMessageSecuritySupport.signMessage(messageContext);
- //encode message
+ // encode message
encoder.initialize();
encoder.encode();
} catch (final Exception e) {
log.warn("Can not encode SAML2 Post-Binding response", e);
throw new SamlBindingException("internal.pvp.95",
- new Object[] {PvpConstants.POST, "encoding", e.getMessage()},
+ new Object[] { PvpConstants.POST, "encoding", e.getMessage() },
e);
}
}
-
-
-
-
@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 {
- //TODO: check, if we should re-implement HTTPPostDecoder to collect the last http parameter!!!
- final EaafHttpPostDecoder decode = new EaafHttpPostDecoder();
- decode.setHttpServletRequest(req);
-
- //decode request
- try {
- decode.initialize();
- decode.decode();
-
- } catch (MessageDecodingException | ComponentInitializationException e) {
- throw new SamlBindingException("internal.pvp.95",
- new Object[] {PvpConstants.POST, "decoding", e.getMessage()},
- e);
- }
-
- final MessageContext<SAMLObject> messageContext = decode.getMessageContext();
+ final EaafHttpPostDecoder decode = new EaafHttpPostDecoder(req);
+ final MessageContext<SAMLObject> messageContext = internalMessageDecode(decode, PvpConstants.POST);
- if (SAMLBindingSupport.isSigningCapableBinding(messageContext)) {
+ // 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);
}
- //inject informations into message context that are required for further processing
- injectInboundMessageContexts(messageContext, metadataProvider);
+ // inject informations into message context that are required for further
+ // processing
+ injectInboundMessageContexts(messageContext, metadataProvider, peerEntityRole);
+ final PvpSamlMessageHandlerChain messageValidatorChain =
+ buildMessageValidationChain(req, comparator, metadataProvider);
+ log.trace("Message validation (Signature, ...) on binding-level starts ... ");
+ performMessageValidation(messageValidatorChain, messageContext);
- //TODO: add sig validation!!!
+ log.trace("Message validation successful");
+ return performMessageDecodePostProcessing(messageContext, true);
-
-
- 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(false);
- msg.setRelayState(SAMLBindingSupport.getRelayState(messageContext));
-
- return msg;
}
@Override
@@ -234,5 +197,41 @@ public class PostBinding extends AbstractBinding implements IDecoder, IEncoder {
@Override
public String getSaml2BindingName() {
return SAMLConstants.SAML2_POST_BINDING_URI;
+
+ }
+
+ private PvpSamlMessageHandlerChain buildMessageValidationChain(HttpServletRequest req,
+ URIComparator comparator, IPvp2MetadataProvider metadataProvider) {
+ final PvpSamlMessageHandlerChain messageValidatorChain = new PvpSamlMessageHandlerChain();
+
+ final ReceivedEndpointSecurityHandler endpointSecurityHandler = new ReceivedEndpointSecurityHandler();
+ endpointSecurityHandler.setHttpServletRequest(req);
+ endpointSecurityHandler.setURIComparator(comparator);
+
+ messageValidatorChain.addHandler(new CheckMessageVersionHandler());
+ messageValidatorChain.addHandler(endpointSecurityHandler);
+ messageValidatorChain.addHandler(
+ new EaafSamlProtocolMessageXmlSignatureSecurityHandler(metadataProvider));
+ messageValidatorChain.addHandler(new MessageLifetimeSecurityHandler());
+
+ /*
+ * TODO: maybe we add it in a later version Because: - AuthnRequest replay
+ * should not be a problem on IDP side - Response replay will be not possible,
+ * because EAAF PVP implements countermeasure based on one-time tokens for each
+ * request
+ *
+ */
+ // final MessageReplaySecurityHandler replaySecurityHandler = new
+ // MessageReplaySecurityHandler();
+ // final StorageService replayCacheStorage = null;
+ // final ReplayCache replayCache = new ReplayCache();
+ // replayCache.setId("Message replay cache");
+ // replayCache.setStrict(true);
+ // replayCache.setStorage(replayCacheStorage);
+ // replaySecurityHandler.setReplayCache(replayCache );
+ // messageValidatorChain.addHandler(replaySecurityHandler);
+
+ return messageValidatorChain;
+
}
}