From bee5dd259a4438d45ecd1bcc26dfba12875236d6 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 26 Jun 2018 11:03:48 +0200 Subject: initial commit --- .../modules/pvp2/impl/binding/PostBinding.java | 211 ++++++++++++++++++++ .../modules/pvp2/impl/binding/RedirectBinding.java | 215 +++++++++++++++++++++ .../modules/pvp2/impl/binding/SoapBinding.java | 148 ++++++++++++++ 3 files changed, 574 insertions(+) create mode 100644 eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java create mode 100644 eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java create mode 100644 eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding') 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 new file mode 100644 index 00000000..4bcbed19 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java @@ -0,0 +1,211 @@ +/******************************************************************************* + *******************************************************************************/ +package at.gv.egiz.eaaf.modules.pvp2.impl.binding; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.opensaml.common.SAMLObject; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.decoding.URIComparator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; +import org.opensaml.saml2.core.RequestAbstractType; +import org.opensaml.saml2.core.StatusResponseType; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.ws.message.decoder.MessageDecodingException; +import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.security.SecurityPolicyResolver; +import org.opensaml.ws.security.provider.BasicSecurityPolicy; +import org.opensaml.ws.security.provider.StaticSecurityPolicyResolver; +import org.opensaml.ws.transport.http.HttpServletRequestAdapter; +import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.credential.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration; +import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory; +import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.impl.gui.velocity.VelocityProvider; +import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IDecoder; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +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.HTTPPostEncoderWithOwnTemplate; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EAAFDefaultSAML2Bootstrap; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.PVPSignedRequestPolicyRule; + +@Service("PVPPOSTBinding") +public class PostBinding implements IDecoder, IEncoder { + private static final Logger log = LoggerFactory.getLogger(PostBinding.class); + + @Autowired(required=true) IConfiguration authConfig; + @Autowired(required=true) IGUIFormBuilder guiBuilder; + @Autowired(required=true) IGUIBuilderConfigurationFactory guiConfigFactory; + + public void encodeRequest(HttpServletRequest req, HttpServletResponse resp, + RequestAbstractType request, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) + throws MessageEncodingException, SecurityException { + + try { + //load default PVP security configurations + EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); + + //initialize POST binding encoder with template decoration + IGUIBuilderConfiguration guiConfig = guiConfigFactory.getSPSpecificSAML2PostConfiguration( + pendingReq, + "pvp_postbinding_template.html", + authConfig.getConfigurationRootDirectory()); + + HTTPPostEncoderWithOwnTemplate encoder = new HTTPPostEncoderWithOwnTemplate(guiConfig, guiBuilder, + VelocityProvider.getClassPathVelocityEngine()); + + //set OpenSAML2 process parameter into binding context dao + HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + resp, true); + BasicSAMLMessageContext context = new BasicSAMLMessageContext(); + SingleSignOnService service = new SingleSignOnServiceBuilder().buildObject(); + service.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); + service.setLocation(targetLocation);; + + context.setOutboundSAMLMessageSigningCredential(credentials); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(request); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(relayState); + + encoder.encode(context); + + } catch (Exception e) { + e.printStackTrace(); + throw new SecurityException(e); + } + } + + public void encodeRespone(HttpServletRequest req, HttpServletResponse resp, + StatusResponseType response, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) + throws MessageEncodingException, SecurityException { + + try { + //load default PVP security configurations + EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); + + log.debug("create SAML POSTBinding response"); + + //initialize POST binding encoder with template decoration + IGUIBuilderConfiguration guiConfig = guiConfigFactory.getSPSpecificSAML2PostConfiguration( + pendingReq, + "pvp_postbinding_template.html", + authConfig.getConfigurationRootDirectory()); + HTTPPostEncoderWithOwnTemplate encoder = new HTTPPostEncoderWithOwnTemplate(guiConfig, guiBuilder, + VelocityProvider.getClassPathVelocityEngine()); + + //set OpenSAML2 process parameter into binding context dao + HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + resp, true); + BasicSAMLMessageContext context = new BasicSAMLMessageContext(); + SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + service.setLocation(targetLocation); + context.setOutboundSAMLMessageSigningCredential(credentials); + context.setPeerEntityEndpoint(service); + // context.setOutboundMessage(authReq); + context.setOutboundSAMLMessage(response); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(relayState); + + encoder.encode(context); + + } catch (Exception e) { + e.printStackTrace(); + throw new SecurityException(e); + } + } + + public InboundMessageInterface decode(HttpServletRequest req, + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, + SecurityException { + + HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); + BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); + messageContext + .setInboundMessageTransport(new HttpServletRequestAdapter(req)); + //set metadata descriptor type + if (isSPEndPoint) { + messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); + + } else { + messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); + } + + messageContext.setMetadataProvider(metadataProvider); + + //set security policy context + BasicSecurityPolicy policy = new BasicSecurityPolicy(); + policy.getPolicyRules().add( + new PVPSignedRequestPolicyRule(metadataProvider, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider), + messageContext.getPeerEntityRole())); + SecurityPolicyResolver secResolver = new StaticSecurityPolicyResolver(policy); + messageContext.setSecurityPolicyResolver(secResolver); + + decode.decode(messageContext); + + InboundMessage msg = null; + if (messageContext.getInboundMessage() instanceof RequestAbstractType) { + RequestAbstractType inboundMessage = (RequestAbstractType) messageContext + .getInboundMessage(); + msg = new PVPSProfileRequest(inboundMessage, getSAML2BindingName()); + msg.setEntityID(inboundMessage.getIssuer().getValue()); + + } else if (messageContext.getInboundMessage() instanceof StatusResponseType){ + StatusResponseType inboundMessage = (StatusResponseType) messageContext.getInboundMessage(); + msg = new PVPSProfileResponse(inboundMessage); + msg.setEntityID(inboundMessage.getIssuer().getValue()); + + } else + //create empty container if request type is unknown + msg = new InboundMessage(); + + if (messageContext.getPeerEntityMetadata() != null) + msg.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); + + else { + if (StringUtils.isEmpty(msg.getEntityID())) + log.info("No Metadata found for OA with EntityID " + messageContext.getInboundMessageIssuer()); + } + + + msg.setVerified(true); + msg.setRelayState(messageContext.getRelayState()); + + return msg; + } + + public boolean handleDecode(String action, HttpServletRequest req) { + return (req.getMethod().equals("POST") && action.equals(PVPConstants.POST)); + } + + public String getSAML2BindingName() { + return SAMLConstants.SAML2_POST_BINDING_URI; + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java new file mode 100644 index 00000000..949cbe57 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java @@ -0,0 +1,215 @@ +/******************************************************************************* + *******************************************************************************/ +package at.gv.egiz.eaaf.modules.pvp2.impl.binding; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.opensaml.common.SAMLObject; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.decoding.URIComparator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder; +import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder; +import org.opensaml.saml2.binding.security.SAML2HTTPRedirectDeflateSignatureRule; +import org.opensaml.saml2.core.RequestAbstractType; +import org.opensaml.saml2.core.StatusResponseType; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.ws.message.decoder.MessageDecodingException; +import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.security.SecurityPolicyResolver; +import org.opensaml.ws.security.provider.BasicSecurityPolicy; +import org.opensaml.ws.security.provider.StaticSecurityPolicyResolver; +import org.opensaml.ws.transport.http.HttpServletRequestAdapter; +import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.credential.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IDecoder; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; +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.initialize.EAAFDefaultSAML2Bootstrap; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.PVPAuthRequestSignedRole; + +@Service("PVPRedirectBinding") +public class RedirectBinding implements IDecoder, IEncoder { + + private static final Logger log = LoggerFactory.getLogger(RedirectBinding.class); + + public void encodeRequest(HttpServletRequest req, HttpServletResponse resp, + RequestAbstractType request, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) + throws MessageEncodingException, SecurityException { + + //load default PVP security configurations + EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); + + log.debug("create SAML RedirectBinding response"); + + HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + resp, true); + BasicSAMLMessageContext context = new BasicSAMLMessageContext(); + SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + service.setLocation(targetLocation); + context.setOutboundSAMLMessageSigningCredential(credentials); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(request); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(relayState); + + encoder.encode(context); + } + + public void encodeRespone(HttpServletRequest req, HttpServletResponse resp, + StatusResponseType response, String targetLocation, String relayState, + Credential credentials, IRequest pendingReq) throws MessageEncodingException, SecurityException { + + //load default PVP security configurations + EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); + + log.debug("create SAML RedirectBinding response"); + + HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + resp, true); + BasicSAMLMessageContext context = new BasicSAMLMessageContext(); + SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + service.setLocation(targetLocation); + context.setOutboundSAMLMessageSigningCredential(credentials); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(response); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(relayState); + + encoder.encode(context); + + } + + public InboundMessageInterface decode(HttpServletRequest req, + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, + SecurityException { + + HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder( + new BasicParserPool()); + + BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); + messageContext + .setInboundMessageTransport(new HttpServletRequestAdapter(req)); + + //set metadata descriptor type + if (isSPEndPoint) { + messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); + + } else { + messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); + } + + messageContext.setMetadataProvider(metadataProvider); + + SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + PVPAuthRequestSignedRole signedRole = new PVPAuthRequestSignedRole(); + BasicSecurityPolicy policy = new BasicSecurityPolicy(); + policy.getPolicyRules().add(signedRole); + policy.getPolicyRules().add(signatureRule); + SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( + policy); + messageContext.setSecurityPolicyResolver(resolver); + + //set metadata descriptor type + if (isSPEndPoint) + messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + else + messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + + try { + decode.decode(messageContext); + + //check signature + signatureRule.evaluate(messageContext); + + } catch (SecurityException e) { + if (StringUtils.isEmpty(messageContext.getInboundMessageIssuer())) { + throw e; + + } + + if (metadataProvider instanceof IRefreshableMetadataProvider) { + log.debug("PVP2X message validation FAILED. Reload metadata for entityID: " + messageContext.getInboundMessageIssuer()); + if (!((IRefreshableMetadataProvider) metadataProvider).refreshMetadataProvider(messageContext.getInboundMessageIssuer())) + throw e; + + else { + log.trace("PVP2X metadata reload finished. Check validate message again."); + decode.decode(messageContext); + + //check signature + signatureRule.evaluate(messageContext); + + } + log.trace("Second PVP2X message validation finished"); + + } else { + throw e; + + } + } + + InboundMessage msg = null; + if (messageContext.getInboundMessage() instanceof RequestAbstractType) { + RequestAbstractType inboundMessage = (RequestAbstractType) messageContext + .getInboundMessage(); + msg = new PVPSProfileRequest(inboundMessage, getSAML2BindingName()); + + + } else if (messageContext.getInboundMessage() instanceof StatusResponseType){ + StatusResponseType inboundMessage = (StatusResponseType) messageContext.getInboundMessage(); + msg = new PVPSProfileResponse(inboundMessage); + + } else + //create empty container if request type is unknown + msg = new InboundMessage(); + + if (messageContext.getPeerEntityMetadata() != null) + msg.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); + + else + log.info("No Metadata found for OA with EntityID " + messageContext.getInboundMessageIssuer()); + + msg.setVerified(true); + msg.setRelayState(messageContext.getRelayState()); + + return msg; + } + + public boolean handleDecode(String action, HttpServletRequest req) { + return ((action.equals(PVPConstants.REDIRECT) || action.equals(PVPConstants.SINGLELOGOUT)) + && req.getMethod().equals("GET")); + } + + public String getSAML2BindingName() { + return SAMLConstants.SAML2_REDIRECT_BINDING_URI; + } +} 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 new file mode 100644 index 00000000..2c2e0d77 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java @@ -0,0 +1,148 @@ +/******************************************************************************* + *******************************************************************************/ +package at.gv.egiz.eaaf.modules.pvp2.impl.binding; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.opensaml.common.SAMLObject; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.decoding.URIComparator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder; +import org.opensaml.saml2.core.RequestAbstractType; +import org.opensaml.saml2.core.StatusResponseType; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.ws.message.decoder.MessageDecodingException; +import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.soap.soap11.Envelope; +import org.opensaml.ws.soap.soap11.decoder.http.HTTPSOAP11Decoder; +import org.opensaml.ws.transport.http.HttpServletRequestAdapter; +import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.signature.SignableXMLObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IDecoder; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +import at.gv.egiz.eaaf.modules.pvp2.exception.AttributQueryException; +import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PVPSProfileRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EAAFDefaultSAML2Bootstrap; + +@Service("PVPSOAPBinding") +public class SoapBinding implements IDecoder, IEncoder { + + private static final Logger log = LoggerFactory.getLogger(SoapBinding.class); + public InboundMessageInterface decode(HttpServletRequest req, + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, + SecurityException, PVP2Exception { + HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); + BasicSAMLMessageContext messageContext = + new BasicSAMLMessageContext(); + messageContext + .setInboundMessageTransport(new HttpServletRequestAdapter( + req)); + messageContext.setMetadataProvider(metadataProvider); + + //TODO: update in a futher version: + // requires a special SignedSOAPRequestPolicyRole because + // messageContext.getInboundMessage() is not directly signed + + //set security context +// BasicSecurityPolicy policy = new BasicSecurityPolicy(); +// policy.getPolicyRules().add( +// new MOAPVPSignedRequestPolicyRule( +// TrustEngineFactory.getSignatureKnownKeysTrustEngine(), +// SPSSODescriptor.DEFAULT_ELEMENT_NAME)); +// SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( +// policy); +// messageContext.setSecurityPolicyResolver(resolver); + + //decode message + soapDecoder.decode(messageContext); + + Envelope inboundMessage = (Envelope) messageContext + .getInboundMessage(); + + if (inboundMessage.getBody() != null) { + List xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); + + if (!xmlElemList.isEmpty()) { + SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); + PVPSProfileRequest request = new PVPSProfileRequest(attrReq, getSAML2BindingName()); + + if (messageContext.getPeerEntityMetadata() != null) + request.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); + + else if (attrReq instanceof RequestAbstractType) { + 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 (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); + } + + public boolean handleDecode(String action, HttpServletRequest req) { + return (req.getMethod().equals("POST") && + (action.equals(PVPConstants.SOAP) || action.equals(PVPConstants.ATTRIBUTEQUERY))); + } + + public void encodeRequest(HttpServletRequest req, HttpServletResponse resp, + RequestAbstractType request, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) + throws MessageEncodingException, SecurityException, PVP2Exception { + + } + + public void encodeRespone(HttpServletRequest req, HttpServletResponse resp, + StatusResponseType response, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) + throws MessageEncodingException, SecurityException, PVP2Exception { + + //load default PVP security configurations + EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); + + HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); + HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + resp, true); + BasicSAMLMessageContext context = new BasicSAMLMessageContext(); + context.setOutboundSAMLMessageSigningCredential(credentials); + context.setOutboundSAMLMessage(response); + context.setOutboundMessageTransport(responseAdapter); + + encoder.encode(context); + + } + + public String getSAML2BindingName() { + return SAMLConstants.SAML2_SOAP11_BINDING_URI; + } + +} -- cgit v1.2.3