diff options
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at')
7 files changed, 132 insertions, 97 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvp2MetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvp2MetadataProvider.java index 184a3adb..ca3aa844 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvp2MetadataProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvp2MetadataProvider.java @@ -39,4 +39,11 @@ public interface IPvp2MetadataProvider extends RefreshableMetadataResolver { @Nullable EntityDescriptor getEntityDescriptor(@Nonnull String entityID) throws ResolverException; + + /** + * Destroy this Metadata resolver, if it supports destroying. + * + */ + void doDestroy(); + } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpAttributeBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpAttributeBuilder.java index 92e75e17..c05b96f3 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpAttributeBuilder.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpAttributeBuilder.java @@ -21,10 +21,11 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.builder; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.ServiceLoader; + +import org.opensaml.saml.saml2.core.Attribute; +import org.opensaml.saml.saml2.metadata.RequestedAttribute; import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder; import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; @@ -33,64 +34,17 @@ import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException; import at.gv.egiz.eaaf.core.exceptions.InvalidDateFormatAttributeException; import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException; +import at.gv.egiz.eaaf.core.impl.idp.builder.AttributeBuilderRegistration; import at.gv.egiz.eaaf.core.impl.idp.builder.attributes.PvpMetadata; import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidDateFormatException; import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import lombok.extern.slf4j.Slf4j; -import org.opensaml.saml.saml2.core.Attribute; -import org.opensaml.saml.saml2.metadata.RequestedAttribute; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +@Slf4j public class PvpAttributeBuilder { - private static final Logger log = LoggerFactory.getLogger(PvpAttributeBuilder.class); - private static IAttributeGenerator<Attribute> generator = new SamlAttributeGenerator(); - private static HashMap<String, IAttributeBuilder> builders; - - private static ServiceLoader<IAttributeBuilder> attributBuilderLoader = - ServiceLoader.load(IAttributeBuilder.class); - - private static void addBuilder(final IAttributeBuilder builder) { - builders.put(builder.getName(), builder); - } - - static { - builders = new HashMap<>(); - - log.info("Loading protocol attribut-builder modules:"); - if (attributBuilderLoader != null) { - final Iterator<IAttributeBuilder> moduleLoaderInterator = attributBuilderLoader.iterator(); - while (moduleLoaderInterator.hasNext()) { - try { - final IAttributeBuilder modul = moduleLoaderInterator.next(); - log.info("Loading attribut-builder Modul Information: " + modul.getName()); - addBuilder(modul); - - } catch (final Throwable e) { - log.error("Check configuration! " + "Some attribute-builder modul" - + " is not a valid IAttributeBuilder", e); - } - } - } - - log.info("Loading attribute-builder modules done"); - - } - - /** - * Get a specific attribute builder. - * - * @param name Attribute-builder friendly name - * - * @return Attribute-builder with this name or null if builder does not exists - */ - public static IAttributeBuilder getAttributeBuilder(final String name) { - return builders.get(name); - - } /** * Build an SAML2 attribute. @@ -102,8 +56,9 @@ public class PvpAttributeBuilder { public static Attribute buildAttribute(final String name, final String value) { log.warn("Attribute value: {} is NOT injected", value); - if (builders.containsKey(name)) { - return builders.get(name).buildEmpty(generator); + if (AttributeBuilderRegistration.containsBuilder(name)) { + return AttributeBuilderRegistration.getAttributeBuilder(name).buildEmpty(generator); + } return null; } @@ -120,9 +75,9 @@ public class PvpAttributeBuilder { */ public static Attribute buildAttribute(final String name, final ISpConfiguration oaParam, final IAuthData authData) throws Pvp2Exception, AttributeBuilderException { - if (builders.containsKey(name)) { + if (AttributeBuilderRegistration.containsBuilder(name)) { try { - return builders.get(name).build(oaParam, authData, generator); + return AttributeBuilderRegistration.getAttributeBuilder(name).build(oaParam, authData, generator); } catch (final AttributeBuilderException e) { if (e instanceof UnavailableAttributeException) { throw e; @@ -146,8 +101,8 @@ public class PvpAttributeBuilder { * @return SAML2 attribute */ public static Attribute buildEmptyAttribute(final String name) { - if (builders.containsKey(name)) { - return builders.get(name).buildEmpty(generator); + if (AttributeBuilderRegistration.containsBuilder(name)) { + return AttributeBuilderRegistration.getAttributeBuilder(name).buildEmpty(generator); } return null; } @@ -157,9 +112,9 @@ public class PvpAttributeBuilder { * * @return */ - public static List<Attribute> buildSupportedEmptyAttributes() { + public static List<Attribute> buildSupportedEmptyAttributes() { final List<Attribute> attributes = new ArrayList<>(); - final Iterator<IAttributeBuilder> builderIt = builders.values().iterator(); + final Iterator<IAttributeBuilder> builderIt = AttributeBuilderRegistration.getAllRegistratedBuilder(); while (builderIt.hasNext()) { final IAttributeBuilder builder = builderIt.next(); if (builder.getClass().isAnnotationPresent(PvpMetadata.class)) { diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java index 3a21b15d..32e82ce4 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java @@ -476,7 +476,12 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec final AbstractMetadataResolver httpprovider = (AbstractMetadataResolver) resolver; log.debug("Destroy metadata resolver with id: {}", httpprovider.getId()); httpprovider.destroy(); - + + } else if (resolver instanceof IPvp2MetadataProvider) { + final IPvp2MetadataProvider httpprovider = (IPvp2MetadataProvider) resolver; + log.debug("Destroy metadata resolver with id: {}", httpprovider.getId()); + httpprovider.doDestroy(); + } else { log.warn("Metadata resolver: {} can not be destroyed. Reason: unsupported type: {}", resolver.getId(), resolver.getClass().getName()); diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java index 1b44afe4..f0291847 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java @@ -1,10 +1,12 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.metadata; + import java.time.Instant; import org.opensaml.core.criterion.EntityIdCriterion; import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver; import org.opensaml.saml.metadata.resolver.filter.MetadataFilter; +import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver; import org.opensaml.saml.saml2.metadata.EntityDescriptor; import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; @@ -113,6 +115,17 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider, IRefre } @Override + public void doDestroy() { + if (internalProvider instanceof AbstractMetadataResolver) { + ((AbstractMetadataResolver) internalProvider).destroy(); + + } else { + log.info("MetadataResolver: {} does not support destroying", + internalProvider.getClass().getName()); + + } + } + public Throwable getLastFailureCause() { return internalProvider.getLastFailureCause(); diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/SignatureTrustEngineDecorator.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/SignatureTrustEngineDecorator.java new file mode 100644 index 00000000..66393bb4 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/SignatureTrustEngineDecorator.java @@ -0,0 +1,41 @@ +package at.gv.egiz.eaaf.modules.pvp2.impl.validation; + +import org.opensaml.security.SecurityException; +import org.opensaml.security.credential.Credential; +import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver; +import org.opensaml.xmlsec.signature.Signature; +import org.opensaml.xmlsec.signature.support.SignatureTrustEngine; + +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.shibboleth.utilities.java.support.resolver.CriteriaSet; + +@AllArgsConstructor +public class SignatureTrustEngineDecorator implements SignatureTrustEngine { + + private SignatureTrustEngine trustEngine; + + @Getter + private IPvp2MetadataProvider metadataProvider; + + @Override + public boolean validate(Signature token, CriteriaSet trustBasisCriteria) throws SecurityException { + return trustEngine.validate(token, trustBasisCriteria); + + } + + @Override + public boolean validate(byte[] signature, byte[] content, String algorithmUri, + CriteriaSet trustBasisCriteria, Credential candidateCredential) throws SecurityException { + return trustEngine.validate(signature, content, algorithmUri, trustBasisCriteria, candidateCredential); + + } + + @Override + public KeyInfoCredentialResolver getKeyInfoResolver() { + return trustEngine.getKeyInfoResolver(); + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/TrustEngineFactory.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/TrustEngineFactory.java index f0758706..fe941f74 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/TrustEngineFactory.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/TrustEngineFactory.java @@ -22,9 +22,6 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.validation; import java.util.ArrayList; import java.util.List; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException; - import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver; import org.opensaml.saml.security.impl.MetadataCredentialResolver; import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver; @@ -33,9 +30,10 @@ import org.opensaml.xmlsec.keyinfo.impl.KeyInfoProvider; import org.opensaml.xmlsec.keyinfo.impl.provider.DSAKeyValueProvider; import org.opensaml.xmlsec.keyinfo.impl.provider.InlineX509DataProvider; import org.opensaml.xmlsec.keyinfo.impl.provider.RSAKeyValueProvider; -import org.opensaml.xmlsec.signature.support.SignatureTrustEngine; import org.opensaml.xmlsec.signature.support.impl.ExplicitKeySignatureTrustEngine; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; @@ -50,7 +48,7 @@ public class TrustEngineFactory { * @throws Pvp2InternalErrorException In case of a TrustEngine initialization * error */ - public static SignatureTrustEngine getSignatureKnownKeysTrustEngine( + public static SignatureTrustEngineDecorator getSignatureKnownKeysTrustEngine( final IPvp2MetadataProvider mdResolver) throws Pvp2InternalErrorException { try { final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>(); @@ -70,10 +68,9 @@ public class TrustEngineFactory { resolver.setKeyInfoCredentialResolver(keyInfoCredentialResolver); resolver.initialize(); - final ExplicitKeySignatureTrustEngine engine = - new ExplicitKeySignatureTrustEngine(resolver, keyInfoCredentialResolver); - - return engine; + return new SignatureTrustEngineDecorator( + new ExplicitKeySignatureTrustEngine(resolver, keyInfoCredentialResolver), + mdResolver); } catch (final ComponentInitializationException e) { log.warn("Initialization of SignatureTrustEngine FAILED.", e); diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java index 9758ff83..2257eba9 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java @@ -32,6 +32,8 @@ import javax.xml.validation.Validator; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.opensaml.core.criterion.EntityIdCriterion; +import org.opensaml.core.xml.io.MarshallingException; +import org.opensaml.core.xml.util.XMLObjectSupport; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.common.xml.SAMLSchemaBuilder; import org.opensaml.saml.common.xml.SAMLSchemaBuilder.SAML1Version; @@ -61,7 +63,6 @@ import org.opensaml.xmlsec.encryption.support.SimpleRetrievalMethodEncryptedKeyR import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver; import org.opensaml.xmlsec.signature.support.SignatureException; import org.opensaml.xmlsec.signature.support.SignatureTrustEngine; -import org.springframework.beans.factory.annotation.Autowired; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -75,10 +76,12 @@ import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; 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.validation.SignatureTrustEngineDecorator; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.net.URIException; import net.shibboleth.utilities.java.support.net.impl.BasicURLComparator; import net.shibboleth.utilities.java.support.resolver.CriteriaSet; +import net.shibboleth.utilities.java.support.xml.SerializeSupport; @Slf4j public class SamlVerificationEngine { @@ -98,13 +101,7 @@ public class SamlVerificationEngine { */ private static final int TIME_JITTER = 3; - - - - - @Autowired(required = true) - IPvp2MetadataProvider metadataProvider; - + /** * Verify signature of a signed SAML2 object. * @@ -141,27 +138,36 @@ public class SamlVerificationEngine { log.debug("PVP2X message validation FAILED. Relead metadata for entityID: {}", msg.getEntityID()); - if (metadataProvider == null || !(metadataProvider instanceof IRefreshableMetadataProvider) - || !((IRefreshableMetadataProvider) metadataProvider) - .refreshMetadataProvider(msg.getEntityID())) { - throw e; - - } else { - log.trace("PVP2X metadata reload finished. Check validate message again."); - - if (msg instanceof PvpSProfileRequest - && ((PvpSProfileRequest) msg).getSamlRequest() instanceof RequestAbstractType) { - verifyRequest((RequestAbstractType) ((PvpSProfileRequest) msg).getSamlRequest(), - sigTrustEngine); + if (sigTrustEngine instanceof SignatureTrustEngineDecorator) { + IPvp2MetadataProvider metadataProvider = + ((SignatureTrustEngineDecorator) sigTrustEngine).getMetadataProvider(); + if (metadataProvider == null || !(metadataProvider instanceof IRefreshableMetadataProvider) + || !((IRefreshableMetadataProvider) metadataProvider).refreshMetadataProvider(msg.getEntityID())) { + + throw e; } else { - verifyIdpResponse(((PvpSProfileResponse) msg).getResponse(), sigTrustEngine); + log.trace("PVP2X metadata reload finished. Check validate message again."); - } + if (msg instanceof PvpSProfileRequest + && ((PvpSProfileRequest) msg).getSamlRequest() instanceof RequestAbstractType) { + verifyRequest((RequestAbstractType) ((PvpSProfileRequest) msg).getSamlRequest(), + sigTrustEngine); - } - log.trace("Second PVP2X message validation finished"); + } else { + verifyIdpResponse(((PvpSProfileResponse) msg).getResponse(), sigTrustEngine); + + } + } + log.trace("Second PVP2X message validation finished"); + + } else { + log.debug("TrustEninge is not of type: {} Dynamic SAML2 metadata refresh not possibile.", + SignatureTrustEngineDecorator.class); + throw e; + + } } } @@ -246,6 +252,7 @@ public class SamlVerificationEngine { // validate each assertion final List<Assertion> validatedassertions = new ArrayList<>(); for (final Assertion saml2assertion : saml2assertions) { + traceLogFullAssertion(saml2assertion); if (internalAssertionValidation(saml2assertion, spEntityID, validateDateTime)) { log.debug("Add valid Assertion:" + saml2assertion.getID()); validatedassertions.add(saml2assertion); @@ -271,9 +278,19 @@ public class SamlVerificationEngine { throw new SamlAssertionValidationExeption(ERROR_16, new Object[] { e.getMessage() }, e); -// } catch (final ConfigurationException e) { -// throw new AssertionValidationExeption("pvp.12", -// new Object[]{loggerName, e.getMessage()}, e); + } + } + + private void traceLogFullAssertion(Assertion saml2assertion) { + if (log.isTraceEnabled()) { + try { + log.trace("Decrypted SAML2 Response:", SerializeSupport.nodeToString( + XMLObjectSupport.getMarshaller(saml2assertion).marshall(saml2assertion))); + + } catch (MarshallingException e) { + log.info("Can NOT trace decrypted SAML2 Assertion", e); + + } } } |