package at.gv.egiz.eaaf.modules.pvp2.impl.verification; import javax.annotation.Nonnull; import javax.annotation.Nullable; import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; import org.opensaml.messaging.context.MessageContext; import org.opensaml.messaging.handler.MessageHandlerException; import org.opensaml.saml.common.binding.security.impl.SAMLProtocolMessageXMLSignatureSecurityHandler; import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext; import lombok.extern.slf4j.Slf4j; @Slf4j public class EaafSamlProtocolMessageXmlSignatureSecurityHandler extends SAMLProtocolMessageXMLSignatureSecurityHandler { private IRefreshableMetadataProvider refreshableMetadataProvider = null; /** * Signature verification handler that reloads SAML2 metadata if signature * verification fails. * * @param metadataProvider Metadata provider implementation. Refreshing is only * possible, if that provider implements * {@link IRefreshableMetadataProvider} */ public EaafSamlProtocolMessageXmlSignatureSecurityHandler( @Nullable IPvp2MetadataProvider metadataProvider) { if (metadataProvider != null) { if (metadataProvider instanceof IRefreshableMetadataProvider) { refreshableMetadataProvider = (IRefreshableMetadataProvider) metadataProvider; } else { log.trace("Refreshing is not supported by {} metadata-provider", metadataProvider.getClass().getSimpleName()); } } } @Override public void doInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException { try { super.doInvoke(messageContext); } catch (final MessageHandlerException e) { if (refreshableMetadataProvider != null) { log.debug("Starting metadata refresh process ... "); if (refreshableMetadataProvider.refreshMetadataProvider( messageContext.getSubcontext(SAMLPeerEntityContext.class).getEntityId())) { log.trace("Refreshing successful. Restarting message evaluation ... "); try { super.doInvoke(messageContext); return; } catch (final MessageHandlerException e1) { log.debug("Signature validation fails twice with second error: {}", e.getMessage()); } } } log.info("Signature validation of SAML message failed. Reason: {}", e.getMessage()); throw new MessageHandlerException( new SamlSigningException("internal.pvp.10", new Object[] { e.getMessage() }, e)); } } }