diff options
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java')
-rw-r--r-- | eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/binding/SoapBinding.java | 203 |
1 files changed, 112 insertions, 91 deletions
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 index 04266d37..e0df2d2a 100644 --- 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 @@ -19,8 +19,6 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.binding; -import java.util.List; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -28,99 +26,105 @@ 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.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.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; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlBindingException; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.EaafMessageContextInitializationHandler; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.PvpSamlMessageHandlerChain; -import org.apache.commons.lang3.StringUtils; -import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.messaging.context.MessageContext; import org.opensaml.messaging.decoder.MessageDecodingException; -import org.opensaml.messaging.encoder.MessageEncodingException; 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.impl.SAMLProtocolAndRoleHandler; +import org.opensaml.saml.common.binding.impl.SAMLSOAPDecoderBodyHandler; +import org.opensaml.saml.common.binding.security.impl.MessageLifetimeSecurityHandler; +import org.opensaml.saml.common.binding.security.impl.SAMLProtocolMessageXMLSignatureSecurityHandler; +import org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.saml2.binding.decoding.impl.HTTPSOAP11Decoder; +import org.opensaml.saml.saml2.binding.encoding.impl.HTTPSOAP11Encoder; import org.opensaml.saml.saml2.core.RequestAbstractType; import org.opensaml.saml.saml2.core.StatusResponseType; -import org.opensaml.saml.saml2.metadata.SPSSODescriptor; -import org.opensaml.saml2.metadata.provider.MetadataProvider; -import org.opensaml.security.credential.Credential; -import org.opensaml.soap.soap11.Envelope; -import org.opensaml.ws.transport.http.HttpServletRequestAdapter; -import org.opensaml.ws.transport.http.HttpServletResponseAdapter; -import org.opensaml.xmlsec.signature.SignableXMLObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; +import lombok.extern.slf4j.Slf4j; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.net.URIComparator; -import net.shibboleth.utilities.java.support.xml.BasicParserPool; - -@Service("PVPSOAPBinding") -public class SoapBinding implements IDecoder, IEncoder { - private static final Logger log = LoggerFactory.getLogger(SoapBinding.class); +@Slf4j +public class SoapBinding extends AbstractBinding implements IDecoder, IEncoder { @Override public InboundMessageInterface decode(final HttpServletRequest req, - final HttpServletResponse resp, final MetadataProvider metadataProvider, + final HttpServletResponse resp, final IPvp2MetadataProvider metadataProvider, final boolean isSpEndPoint, final URIComparator comparator) - throws MessageDecodingException, SecurityException, Pvp2Exception { - final HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); - final BasicSAMLMessageContext<SAMLObject, ?, ?> 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); - - final Envelope inboundMessage = (Envelope) messageContext.getInboundMessage(); - - if (inboundMessage.getBody() != null) { - final List<XMLObject> xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); - - if (!xmlElemList.isEmpty()) { - final SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); - final PvpSProfileRequest request = new PvpSProfileRequest(attrReq, getSaml2BindingName()); - - if (messageContext.getPeerEntityMetadata() != null) { - request.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); - } else if (attrReq instanceof RequestAbstractType) { - final 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 (final Exception e) { - log.warn("No Metadata found with EntityID " + attributeRequest.getIssuer().getValue()); - } - } - - request.setVerified(false); - return request; - - } + throws Pvp2Exception { + + try { + final HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(); + + final PvpSamlMessageHandlerChain messageValidatorChain = new PvpSamlMessageHandlerChain(); + soapDecoder.setBodyHandler(messageValidatorChain); + + final SAMLProtocolMessageXMLSignatureSecurityHandler msgSignatureValidationHandler = + new SAMLProtocolMessageXMLSignatureSecurityHandler(); + + messageValidatorChain.addHandler(new EaafMessageContextInitializationHandler()); + messageValidatorChain.addHandler(new CheckMessageVersionHandler()); + messageValidatorChain.addHandler(new SAMLProtocolAndRoleHandler()); + messageValidatorChain.addHandler(msgSignatureValidationHandler); + messageValidatorChain.addHandler(new MessageLifetimeSecurityHandler()); + messageValidatorChain.addHandler(new SAMLSOAPDecoderBodyHandler()); + + // decode message + soapDecoder.initialize(); + soapDecoder.decode(); + + final MessageContext<SAMLObject> messageContext = soapDecoder.getMessageContext(); + messageContext.getMessage(); + + } catch (MessageDecodingException | ComponentInitializationException e) { + throw new SamlBindingException("internal.pvp.95", + new Object[] { PvpConstants.POST, "decoding", e.getMessage() }, + e); } +// final Envelope inboundMessage = (Envelope) messageContext.getMessage(); +// +// if (inboundMessage.getBody() != null) { +// final List<XMLObject> xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); +// +// if (!xmlElemList.isEmpty()) { +// final SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); +// final PvpSProfileRequest request = new PvpSProfileRequest(attrReq, getSaml2BindingName()); +// +// if (messageContext.getPeerEntityMetadata() != null) { +// request.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); +// +// } else if (attrReq instanceof RequestAbstractType) { +// final 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 (final 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); } @@ -134,30 +138,47 @@ public class SoapBinding implements IDecoder, IEncoder { @Override public void encodeRequest(final HttpServletRequest req, final HttpServletResponse resp, final RequestAbstractType request, final String targetLocation, final String relayState, - final Credential credentials, final IRequest pendingReq) - throws MessageEncodingException, SecurityException, Pvp2Exception { + final EaafX509Credential credentials, final IRequest pendingReq) + throws Pvp2Exception { + throw new RuntimeException("Method not supported!!!"); } @Override - public void encodeRespone(final HttpServletRequest req, final HttpServletResponse resp, + public void encodeResponse(final HttpServletRequest req, final HttpServletResponse resp, final StatusResponseType response, final String targetLocation, final String relayState, - final Credential credentials, final IRequest pendingReq) - throws MessageEncodingException, SecurityException, Pvp2Exception { + final EaafX509Credential credentials, final IRequest pendingReq) + throws Pvp2Exception { + + try { + final HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); + encoder.setHttpServletResponse(resp); + + // inject message context + final MessageContext<SAMLObject> messageContext = buildBasicMessageContext(encoder, response); - // load default PVP security configurations - EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + // inject signing context + messageContext.addSubcontext(injectSigningInfos(credentials)); - final HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); - final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(resp, true); - final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = - new BasicSAMLMessageContext<>(); - context.setOutboundSAMLMessageSigningCredential(credentials); - context.setOutboundSAMLMessage(response); - context.setOutboundMessageTransport(responseAdapter); + // set endpoint url + messageContext.addSubcontext(injectEndpointInfos(response, targetLocation)); - encoder.encode(context); + // set relayState of exists + SAMLBindingSupport.setRelayState(messageContext, relayState); + // sign SAML2 message + SAMLMessageSecuritySupport.signMessage(messageContext); + + // encode message + encoder.initialize(); + encoder.encode(); + } catch (final Exception e) { + log.warn("Can not encode SAML2 SOAP-Binding response", e); + throw new SamlBindingException("internal.pvp.95", + new Object[] { PvpConstants.SOAP, "encoding", e.getMessage() }, + e); + + } } @Override |