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 +++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/PostBinding.java') 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; + } +} -- cgit v1.2.3