diff options
author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2018-06-26 11:03:48 +0200 |
---|---|---|
committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2018-06-26 11:03:48 +0200 |
commit | bee5dd259a4438d45ecd1bcc26dfba12875236d6 (patch) | |
tree | fe1cf7a35cd15dee5fb3c05de0341aa63bf743e0 /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java | |
download | EAAF-Components-bee5dd259a4438d45ecd1bcc26dfba12875236d6.tar.gz EAAF-Components-bee5dd259a4438d45ecd1bcc26dfba12875236d6.tar.bz2 EAAF-Components-bee5dd259a4438d45ecd1bcc26dfba12875236d6.zip |
initial commit
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java')
-rw-r--r-- | eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/RedirectBinding.java | 215 |
1 files changed, 215 insertions, 0 deletions
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<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); + 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<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); + 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<SAMLObject, ?, ?> messageContext = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); + 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; + } +} |