diff options
Diffstat (limited to 'eaaf_modules')
197 files changed, 13424 insertions, 13228 deletions
diff --git a/eaaf_modules/eaaf_module_auth_sl20/pom.xml b/eaaf_modules/eaaf_module_auth_sl20/pom.xml index 2153dfaa..f293f37e 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/pom.xml +++ b/eaaf_modules/eaaf_module_auth_sl20/pom.xml @@ -1,14 +1,17 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>at.gv.egiz.eaaf</groupId> <artifactId>eaaf_modules</artifactId> - <version>1.0.14-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> </parent> <artifactId>eaaf_module_auth_sl20</artifactId> <name>Generic SL2.0 authentication</name> - - <licenses> + + <licenses> <license> <name>European Union Public License, version 1.2 (EUPL-1.2)</name> <url>https://opensource.org/licenses/EUPL-1.2</url> @@ -24,37 +27,37 @@ <organizationUrl>https://www.egiz.gv.at</organizationUrl> </developer> </developers> - + <dependencies> - <dependency> - <groupId>at.gv.egiz.eaaf</groupId> - <artifactId>eaaf-core</artifactId> - <version>${egiz.eaaf.version}</version> - </dependency> - <dependency> - <groupId>org.bitbucket.b_c</groupId> - <artifactId>jose4j</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <scope>provided</scope> - </dependency> + <dependency> + <groupId>at.gv.egiz.eaaf</groupId> + <artifactId>eaaf-core</artifactId> + <version>${egiz.eaaf.version}</version> + </dependency> + <dependency> + <groupId>org.bitbucket.b_c</groupId> + <artifactId>jose4j</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>provided</scope> + </dependency> </dependencies> - + <build> - <resources> - <resource> - <directory>src/main/resources</directory> - </resource> - </resources> - - <plugins> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + </resources> + + <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> @@ -70,13 +73,13 @@ <artifactId>maven-jar-plugin</artifactId> <version>3.1.1</version> <configuration> - <archive> - <manifest> - <addClasspath>true</addClasspath> - <addDefaultImplementationEntries>true</addDefaultImplementationEntries> - <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> - </manifest> - </archive> + <archive> + <manifest> + <addClasspath>true</addClasspath> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + </manifest> + </archive> </configuration> </plugin> @@ -92,23 +95,23 @@ </filesets> </configuration> </plugin> - + <!-- enable co-existence of testng and junit --> - <plugin> - <artifactId>maven-surefire-plugin</artifactId> - <version>${surefire.version}</version> - <configuration> - <threadCount>1</threadCount> - </configuration> - <dependencies> - <dependency> - <groupId>org.apache.maven.surefire</groupId> - <artifactId>surefire-junit47</artifactId> - <version>${surefire.version}</version> - </dependency> - </dependencies> - </plugin> - </plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + <configuration> + <threadCount>1</threadCount> + </configuration> + <dependencies> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit47</artifactId> + <version>${surefire.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> </build> - + </project>
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java index 7e306f25..4009796f 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java @@ -2,129 +2,145 @@ package at.gv.egiz.eaaf.modules.auth.sl20; import java.util.Arrays; import java.util.List; - import javax.annotation.PostConstruct; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; +import at.gv.egiz.eaaf.core.api.idp.IspConfiguration; import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.impl.idp.auth.AbstractAuthenticationManager; import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; /** + * AuthModule to select a Securtiy-Layer 2.0 based authentication process. + * * @author tlenz * */ -public abstract class AbstractSL20AuthenticationModulImpl implements AuthModule { - private static final Logger log = LoggerFactory.getLogger(AbstractSL20AuthenticationModulImpl.class); - - private int priority = 3; - public static final List<String> VDA_TYPE_IDS = Arrays.asList("1", "2", "3", "4"); - - @Autowired(required=true) protected IConfiguration authConfig; - @Autowired(required=true) private AbstractAuthenticationManager authManager; - - @Override - public int getPriority() { - return priority; - } - - /** - * Sets the priority of this module. Default value is {@code 0}. - * @param priority The priority. - */ - public void setPriority(int priority) { - this.priority = priority; - } - - @PostConstruct - protected void initalSL20Authentication() { - //parameter to whiteList - authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE); - authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE); - - } - - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext) - */ - @Override - public String selectProcess(ExecutionContext context, IRequest pendingReq) { - final ISPConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); - - if (spConfig == null) { - log.error("Suspect state. NO SP CONFIGURATION IN CONTEXT!"); - throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN CONTEXT!"); - - } - - final String sl20ClientTypeHeader = (String) context.get(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE.toLowerCase()); - final String sl20VDATypeHeader = (String) context.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase()); - - if (authConfig.getBasicConfigurationBoolean(getGeneralConfigPropertyNameEnableModule(), getGeneralConfigPropertyNameEnableModuleDefault())) { - if (spConfig != null && - StringUtils.isNotEmpty(spConfig.getConfigurationValue(getSPConfigPropertyNameEnableModule())) && - Boolean.valueOf(spConfig.getConfigurationValue(getSPConfigPropertyNameEnableModule()))) { - log.debug("SL2.0 is enabled for " + spConfig.getUniqueIdentifier()); - log.trace(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + ": " + sl20ClientTypeHeader); - log.trace(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE + ": " + sl20VDATypeHeader); - return getProcessName(); - - } else { - log.trace("SL2.0 is NOT enabled for " + spConfig.getUniqueIdentifier()); - return null; - - } - - } else { - log.trace("SL2.0 is NOT enabled with property: {}", getGeneralConfigPropertyNameEnableModule()); - return null; - - } - - } - - /** - * Get the general configuration-key that holds the enabled key for this authentication module - * - * @return - */ - public abstract String getGeneralConfigPropertyNameEnableModule(); - - /** - * Get the default value of the general configuration-key that holds the enabled key for this authentication module - * - * @return - */ - public abstract boolean getGeneralConfigPropertyNameEnableModuleDefault(); - - /** - * Get the SP specific configuration-key that holds the enabled key for this authentication module - * - * @return configuration key for SP configuration - */ - public abstract String getSPConfigPropertyNameEnableModule(); - - /** - * Get the name of this specific SL2.0 process - * - * @return - */ - public abstract String getProcessName(); - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() - */ - @Override - public abstract String[] getProcessDefinitions(); +public abstract class AbstractSL20AuthenticationModulImpl implements AuthModule { + private static final Logger log = + LoggerFactory.getLogger(AbstractSL20AuthenticationModulImpl.class); + + private int priority = 3; + public static final List<String> VDA_TYPE_IDS = Arrays.asList("1", "2", "3", "4"); + + @Autowired(required = true) + protected IConfiguration authConfig; + @Autowired(required = true) + private AbstractAuthenticationManager authManager; + + @Override + public int getPriority() { + return priority; + } + + /** + * Sets the priority of this module. Default value is {@code 0}. + * + * @param priority The priority. + */ + public void setPriority(final int priority) { + this.priority = priority; + } + + @PostConstruct + protected void initalSL20Authentication() { + // parameter to whiteList + authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE); + authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE); + + } + + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process + * .api.ExecutionContext) + */ + @Override + public String selectProcess(final ExecutionContext context, final IRequest pendingReq) { + final IspConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); + + if (spConfig == null) { + log.error("Suspect state. NO SP CONFIGURATION IN CONTEXT!"); + throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN CONTEXT!"); + + } + + final String sl20ClientTypeHeader = + (String) context.get(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE.toLowerCase()); + final String sl20VdaTypeHeader = + (String) context.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase()); + + if (authConfig.getBasicConfigurationBoolean(getGeneralConfigPropertyNameEnableModule(), + getGeneralConfigPropertyNameEnableModuleDefault())) { + if (spConfig != null + && StringUtils + .isNotEmpty(spConfig.getConfigurationValue(getSpConfigPropertyNameEnableModule())) + && Boolean + .valueOf(spConfig.getConfigurationValue(getSpConfigPropertyNameEnableModule()))) { + log.debug("SL2.0 is enabled for " + spConfig.getUniqueIdentifier()); + log.trace(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + ": " + sl20ClientTypeHeader); + log.trace(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE + ": " + sl20VdaTypeHeader); + return getProcessName(); + + } else { + log.trace("SL2.0 is NOT enabled for " + spConfig.getUniqueIdentifier()); + return null; + + } + + } else { + log.trace("SL2.0 is NOT enabled with property: {}", + getGeneralConfigPropertyNameEnableModule()); + return null; + + } + + } + + /** + * Get the general configuration-key that holds the enabled key for this authentication module. + * + * @return + */ + public abstract String getGeneralConfigPropertyNameEnableModule(); + + /** + * Get the default value of the general configuration-key that holds the enabled key for this + * authentication module. + * + * @return + */ + public abstract boolean getGeneralConfigPropertyNameEnableModuleDefault(); + + /** + * Get the SP specific configuration-key that holds the enabled key for this authentication module. + * + * @return configuration key for SP configuration + */ + public abstract String getSpConfigPropertyNameEnableModule(); + + /** + * Get the name of this specific SL2.0 process. + * + * @return + */ + public abstract String getProcessName(); + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() + */ + @Override + public abstract String[] getProcessDefinitions(); } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java index a1490d2b..a8460911 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java @@ -1,58 +1,75 @@ package at.gv.egiz.eaaf.modules.auth.sl20; public class Constants { - - public static final String CONFIG_PROP_PREFIX = "modules.sl20"; - public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID = CONFIG_PROP_PREFIX + ".vda.urls.qualeID."; - - public static final String CONFIG_PROP_VDA_AUTHBLOCK_TRANSFORMATION_ID = CONFIG_PROP_PREFIX + ".vda.authblock.transformation.id"; - public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH = CONFIG_PROP_PREFIX + ".security.keystore.path"; - public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD = CONFIG_PROP_PREFIX + ".security.keystore.password"; - public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS = CONFIG_PROP_PREFIX + ".security.sign.alias"; - public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD = CONFIG_PROP_PREFIX + ".security.sign.password"; - public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS = CONFIG_PROP_PREFIX + ".security.encryption.alias";; - public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD = CONFIG_PROP_PREFIX + ".security.encryption.password"; - - public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT = "default"; - public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT = CONFIG_PROP_VDA_ENDPOINT_QUALeID + CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT; - public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST = CONFIG_PROP_VDA_ENDPOINT_QUALeID + "list"; - public static final String CONFIG_PROP_SP_LIST = CONFIG_PROP_PREFIX + ".sp.entityIds."; - - public static final String CONFIG_PROP_DISABLE_EID_VALIDATION = CONFIG_PROP_PREFIX + ".security.eID.validation.disable"; - public static final String CONFIG_PROP_ENABLE_EID_ENCRYPTION = CONFIG_PROP_PREFIX + ".security.eID.encryption.enabled"; - public static final String CONFIG_PROP_FORCE_EID_ENCRYPTION = CONFIG_PROP_PREFIX + ".security.eID.encryption.required"; - public static final String CONFIG_PROP_FORCE_EID_SIGNED_RESULT = CONFIG_PROP_PREFIX + ".security.eID.signed.result.required"; - - public static final String CONFIG_PROP_IPC_RETURN_URL = CONFIG_PROP_PREFIX + ".testing.ipc.return.url"; - public static final String CONFIG_PROP_HTTP_REDIRECT_CODE = CONFIG_PROP_PREFIX + ".testing.redirect.http.code"; - public static final String CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE = "303"; - - public static final String CONFIG_PROP_SP_ENABLE_SL20_AUTHENTICATION = "auth.sl20.enabled"; - public static final String CONFIG_PROP_SP_SL20_ENDPOINT_LIST = "auth.sl20.endpoints"; - - public static final String PENDING_REQ_STORAGE_PREFIX = "SL20_AUTH_"; - - /** - * Only dummy data for development!!!!!! - */ - public static final String DUMMY_SIGNING_CERT = - "MIIC9zCCAd8CBFretWcwDQYJKoZIhvcNAQEOBQAwQDELMAkGA1UEBhMCQVQxDTAL\n" + - "BgNVBAoMBEVHSVoxIjAgBgNVBAMMGW93biBkdW1teSBtZXRhZGF0YSBzaWduZXIw\n" + - "HhcNMTgwNDI0MDQ0MTExWhcNMjEwMTE3MDQ0MTExWjBAMQswCQYDVQQGEwJBVDEN\n" + - "MAsGA1UECgwERUdJWjEiMCAGA1UEAwwZb3duIGR1bW15IG1ldGFkYXRhIHNpZ25l\n" + - "cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW5trHH\n" + - "Rb1s60QtGNp2v1nfMg1R6h7SzygtmO869v5bqrVBBVGmujslr7W8cZ2DLmJoQx1N\n" + - "WwhccjXTHpNPw0B70qHGch2uRNkqkizSOlwth0Ll2DJtzxTolbajYdg+xppXScUq\n" + - "WNlNZndauPSnB2CESgNkaUou4x4YVSDInugAtLvdLx8rf2YcuidI6UIXxeSZr3VO\n" + - "Z12YtddzcJ+lwh7OX8B0UvLsdYjKjefjEudyuNBmVwLv4K2LsFhSqgE1CAzk3oCb\n" + - "V2A84klaWVPiXoBiOucyouvX781WVp1aCBp0QA8gpJH7/2wRsdPQ90tjMzM7dcgY\n" + - "LDkCAwEAATANBgkqhkiG9w0BAQ4FAAOCAQEAQuYRQcCNLDYU1ItliYz9f28+KDyU\n" + - "8WjF3NDZrlJbGSKQ4n7wkBfxdK3zprmpHadWDB+aZaPt/+voE2FduzPiLUDlpazN\n" + - "60JJ5/YHZ3q9MZvdoNg6rjkpioWatoj/smUkT6oUWL/gp8tH12fOd2oJygBqXMve\n" + - "3y3qVCghnjRaMYuXcScTZcjH9yebkTLygirtw34oGVb7t+HwbtcN65fUIBly6Rcl\n" + - "8NV3pwOKhXFKDAqXUpvhebL4+tWOqPdqfIfGaE6rELfTf3icGY3CQCzDz5Gp0Ptc\n" + - "TfQqm64xnhtAruXNJXWg2ptg+GuQgWnJUgQ8wLNMxw9XdeEwlQo5dL6xmg=="; - - public static final String DUMMY_SIGNING_CERT_FINGERPRINT = "IwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW"; + + public static final String CONFIG_PROP_PREFIX = "modules.sl20"; + public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID = + CONFIG_PROP_PREFIX + ".vda.urls.qualeID."; + + public static final String CONFIG_PROP_VDA_AUTHBLOCK_TRANSFORMATION_ID = + CONFIG_PROP_PREFIX + ".vda.authblock.transformation.id"; + public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH = + CONFIG_PROP_PREFIX + ".security.keystore.path"; + public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD = + CONFIG_PROP_PREFIX + ".security.keystore.password"; + public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS = + CONFIG_PROP_PREFIX + ".security.sign.alias"; + public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD = + CONFIG_PROP_PREFIX + ".security.sign.password"; + public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS = + CONFIG_PROP_PREFIX + ".security.encryption.alias"; + public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD = + CONFIG_PROP_PREFIX + ".security.encryption.password"; + + public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT = "default"; + public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT = + CONFIG_PROP_VDA_ENDPOINT_QUALeID + CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT; + public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST = + CONFIG_PROP_VDA_ENDPOINT_QUALeID + "list"; + public static final String CONFIG_PROP_SP_LIST = CONFIG_PROP_PREFIX + ".sp.entityIds."; + + public static final String CONFIG_PROP_DISABLE_EID_VALIDATION = + CONFIG_PROP_PREFIX + ".security.eID.validation.disable"; + public static final String CONFIG_PROP_ENABLE_EID_ENCRYPTION = + CONFIG_PROP_PREFIX + ".security.eID.encryption.enabled"; + public static final String CONFIG_PROP_FORCE_EID_ENCRYPTION = + CONFIG_PROP_PREFIX + ".security.eID.encryption.required"; + public static final String CONFIG_PROP_FORCE_EID_SIGNED_RESULT = + CONFIG_PROP_PREFIX + ".security.eID.signed.result.required"; + + public static final String CONFIG_PROP_IPC_RETURN_URL = + CONFIG_PROP_PREFIX + ".testing.ipc.return.url"; + public static final String CONFIG_PROP_HTTP_REDIRECT_CODE = + CONFIG_PROP_PREFIX + ".testing.redirect.http.code"; + public static final String CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE = "303"; + + public static final String CONFIG_PROP_SP_ENABLE_SL20_AUTHENTICATION = "auth.sl20.enabled"; + public static final String CONFIG_PROP_SP_SL20_ENDPOINT_LIST = "auth.sl20.endpoints"; + + public static final String PENDING_REQ_STORAGE_PREFIX = "SL20_AUTH_"; + + /** + * Only dummy data for development!!!!!!. + */ + public static final String DUMMY_SIGNING_CERT = + "MIIC9zCCAd8CBFretWcwDQYJKoZIhvcNAQEOBQAwQDELMAkGA1UEBhMCQVQxDTAL\n" + + "BgNVBAoMBEVHSVoxIjAgBgNVBAMMGW93biBkdW1teSBtZXRhZGF0YSBzaWduZXIw\n" + + "HhcNMTgwNDI0MDQ0MTExWhcNMjEwMTE3MDQ0MTExWjBAMQswCQYDVQQGEwJBVDEN\n" + + "MAsGA1UECgwERUdJWjEiMCAGA1UEAwwZb3duIGR1bW15IG1ldGFkYXRhIHNpZ25l\n" + + "cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW5trHH\n" + + "Rb1s60QtGNp2v1nfMg1R6h7SzygtmO869v5bqrVBBVGmujslr7W8cZ2DLmJoQx1N\n" + + "WwhccjXTHpNPw0B70qHGch2uRNkqkizSOlwth0Ll2DJtzxTolbajYdg+xppXScUq\n" + + "WNlNZndauPSnB2CESgNkaUou4x4YVSDInugAtLvdLx8rf2YcuidI6UIXxeSZr3VO\n" + + "Z12YtddzcJ+lwh7OX8B0UvLsdYjKjefjEudyuNBmVwLv4K2LsFhSqgE1CAzk3oCb\n" + + "V2A84klaWVPiXoBiOucyouvX781WVp1aCBp0QA8gpJH7/2wRsdPQ90tjMzM7dcgY\n" + + "LDkCAwEAATANBgkqhkiG9w0BAQ4FAAOCAQEAQuYRQcCNLDYU1ItliYz9f28+KDyU\n" + + "8WjF3NDZrlJbGSKQ4n7wkBfxdK3zprmpHadWDB+aZaPt/+voE2FduzPiLUDlpazN\n" + + "60JJ5/YHZ3q9MZvdoNg6rjkpioWatoj/smUkT6oUWL/gp8tH12fOd2oJygBqXMve\n" + + "3y3qVCghnjRaMYuXcScTZcjH9yebkTLygirtw34oGVb7t+HwbtcN65fUIBly6Rcl\n" + + "8NV3pwOKhXFKDAqXUpvhebL4+tWOqPdqfIfGaE6rELfTf3icGY3CQCzDz5Gp0Ptc\n" + + "TfQqm64xnhtAruXNJXWg2ptg+GuQgWnJUgQ8wLNMxw9XdeEwlQo5dL6xmg=="; + + public static final String DUMMY_SIGNING_CERT_FINGERPRINT = + "IwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW"; } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java index e19ef5fc..af155206 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java @@ -1,16 +1,16 @@ package at.gv.egiz.eaaf.modules.auth.sl20; /** - * Set of event codes uses in Auth-Handler implementation - * + * Set of event codes uses in Auth-Handler implementation. + * * @author tlenz * */ public class EventCodes { - public static final int AUTHPROCESS_SL20_SELECTED = 4111; - public static final int AUTHPROCESS_SL20_ENDPOINT_URL = 4112; - public static final int AUTHPROCESS_SL20_DATAURL_IP = 4113; - - public static final int AUTHPROCESS_SL20_CONSENT_VALID = 4113; + public static final int AUTHPROCESS_SL20_SELECTED = 4111; + public static final int AUTHPROCESS_SL20_ENDPOINT_URL = 4112; + public static final int AUTHPROCESS_SL20_DATAURL_IP = 4113; + + public static final int AUTHPROCESS_SL20_CONSENT_VALID = 4113; } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java index 0c625a9b..7ca4ea87 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java @@ -7,33 +7,34 @@ import com.fasterxml.jackson.databind.JsonNode; public class VerificationResult { - private Boolean validSigned = null; - private List<X509Certificate> certs = null; - private JsonNode payload = null; - - public VerificationResult(JsonNode payload) { - this.payload = payload; - - } - - public VerificationResult(JsonNode string, List<X509Certificate> certs, boolean wasValidSigned) { - this.payload = string; - this.certs = certs; - this.validSigned = wasValidSigned; - - } - - public Boolean isValidSigned() { - return validSigned; - } - public List<X509Certificate> getCertChain() { - return certs; - } - public JsonNode getPayload() { - return payload; - } - - - - + private Boolean validSigned = null; + private List<X509Certificate> certs = null; + private JsonNode payload = null; + + public VerificationResult(final JsonNode payload) { + this.payload = payload; + + } + + public VerificationResult(final JsonNode string, final List<X509Certificate> certs, final boolean wasValidSigned) { + this.payload = string; + this.certs = certs; + this.validSigned = wasValidSigned; + + } + + public Boolean isValidSigned() { + return validSigned; + } + + public List<X509Certificate> getCertChain() { + return certs; + } + + public JsonNode getPayload() { + return payload; + } + + + } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java new file mode 100644 index 00000000..a14fbe9e --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java @@ -0,0 +1,16 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; + +public class SL20EidDataValidationException extends SL20Exception { + private static final long serialVersionUID = 1L; + + public SL20EidDataValidationException(final Object[] parameters) { + super("sl20.07", parameters); + + } + + public SL20EidDataValidationException(final Object[] parameters, final Throwable e) { + super("sl20.07", parameters, e); + + } + +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java index b23b5ca3..12921ad6 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java @@ -1,19 +1,19 @@ package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; -import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; -public class SL20Exception extends EAAFAuthenticationException { +public class SL20Exception extends EaafAuthenticationException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public SL20Exception(String messageId, Object[] parameters) { - super(messageId, parameters); + public SL20Exception(final String messageId, final Object[] parameters) { + super(messageId, parameters); - } - - public SL20Exception(String messageId, Object[] parameters, Throwable wrapped) { - super(messageId, parameters, wrapped); + } - } + public SL20Exception(final String messageId, final Object[] parameters, final Throwable wrapped) { + super(messageId, parameters, wrapped); + + } } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java index eaf55ba3..c751f2c2 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java @@ -2,19 +2,19 @@ package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; public class SL20SecurityException extends SL20Exception { - private static final long serialVersionUID = 3281385988027147449L; + private static final long serialVersionUID = 3281385988027147449L; - public SL20SecurityException(Object[] parameters) { - super("sl20.05", parameters); - } - - public SL20SecurityException(String parameter) { - super("sl20.05", new Object[] {parameter}); - } - - public SL20SecurityException(Object[] parameters, Throwable wrapped) { - super("sl20.05", parameters, wrapped); + public SL20SecurityException(final Object[] parameters) { + super("sl20.05", parameters); + } - } + public SL20SecurityException(final String parameter) { + super("sl20.05", new Object[] {parameter}); + } + + public SL20SecurityException(final Object[] parameters, final Throwable wrapped) { + super("sl20.05", parameters, wrapped); + + } } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java deleted file mode 100644 index 24df735a..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java +++ /dev/null @@ -1,16 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; - -public class SL20eIDDataValidationException extends SL20Exception { - private static final long serialVersionUID = 1L; - - public SL20eIDDataValidationException(Object[] parameters) { - super("sl20.07", parameters); - - } - - public SL20eIDDataValidationException(Object[] parameters, Throwable e) { - super("sl20.07", parameters, e); - - } - -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java deleted file mode 100644 index 1f521ebc..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java +++ /dev/null @@ -1,17 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; - -public class SLCommandoBuildException extends SL20Exception { - - private static final long serialVersionUID = 1L; - - - public SLCommandoBuildException(String msg) { - super("sl20.01", new Object[]{msg}); - - } - - public SLCommandoBuildException(String msg, Throwable e) { - super("sl20.01", new Object[]{msg}, e); - - } -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java deleted file mode 100644 index 60993e69..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java +++ /dev/null @@ -1,17 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; - -public class SLCommandoParserException extends SL20Exception { - - private static final long serialVersionUID = 1L; - - - public SLCommandoParserException(String msg) { - super("sl20.02", new Object[]{msg}); - - } - - public SLCommandoParserException(String msg, Throwable e) { - super("sl20.02", new Object[]{msg}, e); - - } -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java new file mode 100644 index 00000000..bed1cdb0 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java @@ -0,0 +1,17 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; + +public class SlCommandoBuildException extends SL20Exception { + + private static final long serialVersionUID = 1L; + + + public SlCommandoBuildException(final String msg) { + super("sl20.01", new Object[] {msg}); + + } + + public SlCommandoBuildException(final String msg, final Throwable e) { + super("sl20.01", new Object[] {msg}, e); + + } +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java new file mode 100644 index 00000000..dab42631 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java @@ -0,0 +1,17 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; + +public class SlCommandoParserException extends SL20Exception { + + private static final long serialVersionUID = 1L; + + + public SlCommandoParserException(final String msg) { + super("sl20.02", new Object[] {msg}); + + } + + public SlCommandoParserException(final String msg, final Throwable e) { + super("sl20.02", new Object[] {msg}, e); + + } +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualEidRequestTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualEidRequestTask.java new file mode 100644 index 00000000..251b516f --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualEidRequestTask.java @@ -0,0 +1,250 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.tasks; + +import java.security.cert.CertificateEncodingException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; +import at.gv.egiz.eaaf.core.api.idp.IspConfiguration; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; +import at.gv.egiz.eaaf.modules.auth.sl20.Constants; +import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes; +import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20HttpBindingUtils; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonExtractorUtils; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonBuilderUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.jose4j.base64url.Base64Url; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public abstract class AbstractCreateQualEidRequestTask extends AbstractAuthServletTask { + private static final Logger log = LoggerFactory.getLogger(AbstractCreateQualEidRequestTask.class); + + @Autowired(required = true) + private IHttpClientFactory httpClientFactory; + @Autowired(required = true) + protected IConfigurationWithSP authConfigWithSp; + + @Override + public void execute(final ExecutionContext executionContext, final HttpServletRequest request, + final HttpServletResponse response) throws TaskExecutionException { + + log.debug("Starting SL2.0 authentication process .... "); + + revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_SELECTED, "sl20auth"); + + try { + // get service-provider configuration + final IspConfiguration oaConfig = pendingReq.getServiceProviderConfiguration(); + + if (oaConfig == null) { + log.warn("No SP configuration in pendingReq!"); + throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN PendingRequest!"); + + } + + // get basic configuration parameters + final String vdaQualEidDUrl = extractVdaUrlForSpecificOa(oaConfig, executionContext); + if (StringUtils.isEmpty(vdaQualEidDUrl)) { + log.error("NO VDA URL for qualified eID (" + + Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT + ")"); + throw new SL20Exception("sl20.03", new Object[] {"NO VDA URL for qualified eID"}); + + } + + log.debug("Use {} as VDA end-point", vdaQualEidDUrl); + pendingReq.setRawDataToTransaction( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, + vdaQualEidDUrl); + revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_ENDPOINT_URL, vdaQualEidDUrl); + + // create SL2.0 command for qualified eID + final String signedQualEidCommand = buildSignedQualifiedEidCommand(); + + // build request container + final String qualEidReqId = Random.nextProcessReferenceValue(); + final ObjectNode sl20Req = + SL20JsonBuilderUtils.createGenericRequest(qualEidReqId, null, null, signedQualEidCommand); + + // build http POST request + final HttpPost httpReq = new HttpPost(new URIBuilder(vdaQualEidDUrl).build()); + final List<NameValuePair> parameters = new ArrayList<>(); + parameters.add(new BasicNameValuePair(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, + Base64Url.encode(sl20Req.toString().getBytes()))); + httpReq.setEntity(new UrlEncodedFormEntity(parameters)); + + // build http GET request + // URIBuilder sl20ReqUri = new URIBuilder(vdaQualeIDUrl); + // sl20ReqUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, + // Base64Url.encode(sl20Req.toString().getBytes())); + // HttpGet httpReq = new HttpGet(sl20ReqUri.build()); + + // set native client header + httpReq.addHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE, + SL20Constants.HTTP_HEADER_VALUE_NATIVE); + + log.trace("Request VDA via SL20 with: " + Base64Url.encode(sl20Req.toString().getBytes())); + + // request VDA + final HttpResponse httpResp = httpClientFactory.getHttpClient(false).execute(httpReq); + + // parse response + log.info("Receive response from VDA ... "); + final JsonNode sl20Resp = SL20JsonExtractorUtils.getSL20ContainerFromResponse(httpResp); + final VerificationResult respPayloadContainer = + SL20JsonExtractorUtils.extractSL20PayLoad(sl20Resp, null, false); + + if (respPayloadContainer.isValidSigned() == null) { + log.debug("Receive unsigned payLoad from VDA"); + + } + + final JsonNode respPayload = respPayloadContainer.getPayload(); + if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText() + .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT)) { + log.debug("Find 'redirect' command in VDA response ... "); + final JsonNode params = SL20JsonExtractorUtils.getJsonObjectValue(respPayload, + SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, true); + final String redirectUrl = SL20JsonExtractorUtils.getStringValue(params, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, true); + final JsonNode command = SL20JsonExtractorUtils.getJsonObjectValue(params, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, false); + final String signedCommand = SL20JsonExtractorUtils.getStringValue(params, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, false); + + // create forward SL2.0 command + final ObjectNode sl20Forward = sl20Resp.deepCopy(); + SL20JsonBuilderUtils.addOnlyOnceOfTwo(sl20Forward, SL20Constants.SL20_PAYLOAD, + SL20Constants.SL20_SIGNEDPAYLOAD, command.deepCopy(), signedCommand); + + // store pending request + pendingReq.setRawDataToTransaction( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, qualEidReqId); + requestStoreage.storePendingRequest(pendingReq); + + // forward SL2.0 command + // TODO: maybe add SL2ClientType Header from execution context + SL20HttpBindingUtils.writeIntoResponse(request, response, sl20Forward, redirectUrl, + Integer + .parseInt(authConfig.getBasicConfiguration(Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, + Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); + + } else if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText() + .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { + JsonNode result = SL20JsonExtractorUtils.getJsonObjectValue(respPayload, + SL20Constants.SL20_COMMAND_CONTAINER_RESULT, false); + if (result == null) { + result = SL20JsonExtractorUtils.getJsonObjectValue(respPayload, + SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, false); + } + + final String errorCode = SL20JsonExtractorUtils.getStringValue(result, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true); + final String errorMsg = SL20JsonExtractorUtils.getStringValue(result, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, true); + + log.info("Receive SL2.0 error. Code:" + errorCode + " Msg:" + errorMsg); + throw new SL20Exception("sl20.08", new Object[] {errorCode, errorMsg}); + + } else { + // TODO: update to add error handling + log.warn("Received an unrecognized command: " + + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText()); + throw new SlCommandoParserException( + "Received an unrecognized command: " + + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).toString()); + } + + + } catch (final EaafAuthenticationException e) { + throw new TaskExecutionException(pendingReq, + "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e); + + } catch (final Exception e) { + log.warn("SL2.0 Authentication FAILED with a generic error.", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } finally { + TransactionIdUtils.removeTransactionId(); + TransactionIdUtils.removeSessionId(); + + } + + } + + /** + * Create a implementation specific qualified eID SL2.0 command + * + * @param oaConfig + * + * @return signed JWT token as serialized {@link String} + * @throws CertificateEncodingException In case of certificate parsing error + * @throws SL20Exception In case of a SL2.0 error + */ + protected abstract String buildSignedQualifiedEidCommand() + throws CertificateEncodingException, SL20Exception; + + + private String extractVdaUrlForSpecificOa(final IspConfiguration oaConfig, + final ExecutionContext executionContext) { + + // load SP specific config for development and testing purposes + final String spSpecificVdaEndpoints = + oaConfig.getConfigurationValue(Constants.CONFIG_PROP_SP_SL20_ENDPOINT_LIST); + + // load general configuration + final Map<String, String> endPointMap = authConfigWithSp + .getBasicConfigurationWithPrefix(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST); + endPointMap.put(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT, + authConfig.getBasicConfiguration(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT)); + if (StringUtils.isNotEmpty(spSpecificVdaEndpoints)) { + endPointMap.putAll(KeyValueUtils.convertListToMap(KeyValueUtils + .getListOfCsvValues(KeyValueUtils.normalizeCsvValueString(spSpecificVdaEndpoints)))); + log.debug("Find OA specific SL2.0 endpoints. Updating endPoint list ... "); + + } + + log.trace("Find #" + endPointMap.size() + " SL2.0 endpoints ... "); + + // selection based on request Header + final String sl20VdaTypeHeader = + (String) executionContext.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase()); + if (StringUtils.isNotEmpty(sl20VdaTypeHeader)) { + final String vdaUrl = endPointMap.get(sl20VdaTypeHeader); + if (StringUtils.isNotEmpty(vdaUrl)) { + return vdaUrl.trim(); + } else { + log.info("Can NOT find VDA with Id: " + sl20VdaTypeHeader + ". Use default VDA"); + } + + } + + + log.info("NO specific VDA endpoint requested or found. Use default VDA"); + return endPointMap.get(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT); + + } + +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java deleted file mode 100644 index 85302d83..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java +++ /dev/null @@ -1,227 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.tasks; - -import java.security.cert.CertificateEncodingException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.message.BasicNameValuePair; -import org.jose4j.base64url.Base64Url; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; -import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; -import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; -import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; -import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; -import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; -import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; -import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; -import at.gv.egiz.eaaf.core.impl.utils.Random; -import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils; -import at.gv.egiz.eaaf.modules.auth.sl20.Constants; -import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes; -import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20HttpBindingUtils; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONBuilderUtils; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONExtractorUtils; - -public abstract class AbstractCreateQualeIDRequestTask extends AbstractAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(AbstractCreateQualeIDRequestTask.class); - - @Autowired(required=true) private IHttpClientFactory httpClientFactory; - @Autowired(required=true) protected IConfigurationWithSP authConfigWithSp; - - @Override - public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { - - log.debug("Starting SL2.0 authentication process .... "); - - revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_SELECTED, "sl20auth"); - - try { - //get service-provider configuration - final ISPConfiguration oaConfig = pendingReq.getServiceProviderConfiguration(); - - if (oaConfig == null) { - log.warn("No SP configuration in pendingReq!"); - throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN PendingRequest!"); - - } - - //get basic configuration parameters - final String vdaQualeIDUrl = extractVDAURLForSpecificOA(oaConfig, executionContext); - if (StringUtils.isEmpty(vdaQualeIDUrl)) { - log.error("NO VDA URL for qualified eID (" + Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT + ")"); - throw new SL20Exception("sl20.03", new Object[]{"NO VDA URL for qualified eID"}); - - } - - log.debug("Use {} as VDA end-point", vdaQualeIDUrl) ; - pendingReq.setRawDataToTransaction( - Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, - vdaQualeIDUrl); - revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_ENDPOINT_URL, vdaQualeIDUrl); - - //create SL2.0 command for qualified eID - final String signedQualeIDCommand = buildSignedQualifiedEIDCommand(); - - //build request container - final String qualeIDReqId = Random.nextProcessReferenceValue(); - final ObjectNode sl20Req = SL20JSONBuilderUtils.createGenericRequest(qualeIDReqId, null, null, signedQualeIDCommand); - - //build http POST request - final HttpPost httpReq = new HttpPost(new URIBuilder(vdaQualeIDUrl).build()); - final List<NameValuePair> parameters = new ArrayList<NameValuePair>();; - parameters.add(new BasicNameValuePair(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Req.toString().getBytes()))); - httpReq.setEntity(new UrlEncodedFormEntity(parameters )); - - //build http GET request -// URIBuilder sl20ReqUri = new URIBuilder(vdaQualeIDUrl); -// sl20ReqUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Req.toString().getBytes())); -// HttpGet httpReq = new HttpGet(sl20ReqUri.build()); - - //set native client header - httpReq.addHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE, SL20Constants.HTTP_HEADER_VALUE_NATIVE); - - log.trace("Request VDA via SL20 with: " + Base64Url.encode(sl20Req.toString().getBytes())); - - //request VDA - final HttpResponse httpResp = httpClientFactory.getHttpClient(false).execute(httpReq); - - //parse response - log.info("Receive response from VDA ... "); - final JsonNode sl20Resp = SL20JSONExtractorUtils.getSL20ContainerFromResponse(httpResp); - final VerificationResult respPayloadContainer = SL20JSONExtractorUtils.extractSL20PayLoad(sl20Resp, null, false); - - if (respPayloadContainer.isValidSigned() == null) { - log.debug("Receive unsigned payLoad from VDA"); - - } - - final JsonNode respPayload = respPayloadContainer.getPayload(); - if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText() - .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT)) { - log.debug("Find 'redirect' command in VDA response ... "); - final JsonNode params = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, true); - final String redirectURL = SL20JSONExtractorUtils.getStringValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, true); - final JsonNode command = SL20JSONExtractorUtils.getJSONObjectValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, false); - final String signedCommand = SL20JSONExtractorUtils.getStringValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, false); - - //create forward SL2.0 command - final ObjectNode sl20Forward = sl20Resp.deepCopy(); - SL20JSONBuilderUtils.addOnlyOnceOfTwo(sl20Forward, - SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, - command.deepCopy(), signedCommand); - - //store pending request - pendingReq.setRawDataToTransaction(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, - qualeIDReqId); - requestStoreage.storePendingRequest(pendingReq); - - //forward SL2.0 command - //TODO: maybe add SL2ClientType Header from execution context - SL20HttpBindingUtils.writeIntoResponse(request, response, sl20Forward, redirectURL, - Integer.parseInt(authConfig.getBasicConfiguration(Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); - - } else if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText() - .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { - JsonNode result = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, false); - if (result == null) - result = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, false); - - final String errorCode = SL20JSONExtractorUtils.getStringValue(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true); - final String errorMsg = SL20JSONExtractorUtils.getStringValue(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, true); - - log.info("Receive SL2.0 error. Code:" + errorCode + " Msg:" + errorMsg); - throw new SL20Exception("sl20.08", new Object[]{errorCode, errorMsg}); - - } else { - //TODO: update to add error handling - log.warn("Received an unrecognized command: " + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText()); - throw new SLCommandoParserException("Received an unrecognized command: \" + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).getAsString()"); - } - - - } catch (final EAAFAuthenticationException e) { - throw new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e); - - } catch (final Exception e) { - log.warn("SL2.0 Authentication FAILED with a generic error.", e); - throw new TaskExecutionException(pendingReq, e.getMessage(), e); - - } finally { - TransactionIDUtils.removeTransactionId(); - TransactionIDUtils.removeSessionId(); - - } - - } - - /** - * Create a implementation specific qualified eID SL2.0 command - * @param oaConfig - * - * @return signed JWT token as serialized {@link String} - * @throws CertificateEncodingException - * @throws SLCommandoBuildException - * @throws SL20Exception - */ - protected abstract String buildSignedQualifiedEIDCommand() throws CertificateEncodingException, SL20Exception; - - - private String extractVDAURLForSpecificOA(ISPConfiguration oaConfig, ExecutionContext executionContext) { - - //load SP specific config for development and testing purposes - final String spSpecificVDAEndpoints = oaConfig.getConfigurationValue(Constants.CONFIG_PROP_SP_SL20_ENDPOINT_LIST); - - //load general configuration - final Map<String, String> endPointMap = authConfigWithSp.getBasicConfigurationWithPrefix(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST); - endPointMap.put(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT, authConfig.getBasicConfiguration(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT)); - if (StringUtils.isNotEmpty(spSpecificVDAEndpoints)) { - endPointMap.putAll(KeyValueUtils.convertListToMap( - KeyValueUtils.getListOfCSVValues( - KeyValueUtils.normalizeCSVValueString(spSpecificVDAEndpoints)))); - log.debug("Find OA specific SL2.0 endpoints. Updating endPoint list ... "); - - } - - log.trace("Find #" + endPointMap.size() + " SL2.0 endpoints ... "); - - //selection based on request Header - final String sl20VDATypeHeader = (String) executionContext.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase()); - if (StringUtils.isNotEmpty(sl20VDATypeHeader)) { - final String vdaURL = endPointMap.get(sl20VDATypeHeader); - if (StringUtils.isNotEmpty(vdaURL)) - return vdaURL.trim(); - else - log.info("Can NOT find VDA with Id: " + sl20VDATypeHeader + ". Use default VDA"); - - } - - - log.info("NO specific VDA endpoint requested or found. Use default VDA"); - return endPointMap.get(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT); - - } - -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java new file mode 100644 index 00000000..39cfce05 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java @@ -0,0 +1,344 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.tasks; + +import java.io.IOException; +import java.io.StringWriter; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.utils.DataUrlBuilder; +import at.gv.egiz.eaaf.core.impl.utils.StreamUtils; +import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; +import at.gv.egiz.eaaf.modules.auth.sl20.Constants; +import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes; +import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.IJoseTools; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.JsonMapper; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonBuilderUtils; +import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonExtractorUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ContentType; +import org.jose4j.base64url.Base64Url; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + + +public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask { + private static final Logger log = LoggerFactory.getLogger(AbstractReceiveQualEidTask.class); + + private static final String PATTERN_PENDING_REQ_ID = "#PENDINGREQID#"; + + @Autowired(required = true) + private IJoseTools joseTools; + + @Override + public void execute(final ExecutionContext executionContext, final HttpServletRequest request, + final HttpServletResponse response) throws TaskExecutionException { + String sl20Result = null; + + try { + log.debug("Receiving SL2.0 response process .... "); + JsonNode sl20ReqObj = null; + + // A-Trust does not SET http-header 'SL2ClientType' with value 'native' + // If A-trust sends an error, its maybe FrontChannel on DataURL + // boolean aTrustErrorWorkAround = false; + + try { + // get SL2.0 command or result from HTTP request + final Map<String, String> reqParams = getParameters(request); + sl20Result = reqParams.get(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM); + + if (StringUtils.isEmpty(sl20Result)) { + // Workaround for SIC Handy-Signature, because it sends result in InputStream + final String isReqInput = StreamUtils.readStream(request.getInputStream(), "UTF-8"); + if (StringUtils.isNotEmpty(isReqInput)) { + log.info("Use SIC Handy-Signature work-around!"); + sl20Result = isReqInput.substring("slcommand=".length()); + + } else { + log.info("NO SL2.0 commando or result FOUND."); + throw new SL20Exception("sl20.04", null); + } + + } + + log.trace("Received SL2.0 result: " + sl20Result); + revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_DATAURL_IP, + request.getRemoteAddr()); + + // parse SL2.0 command/result into JSON + try { + sl20ReqObj = + new JsonMapper().getMapper().readTree(Base64Url.decodeToUtf8String(sl20Result)); + + } catch (final JsonParseException e) { + log.warn("SL2.0 command or result is NOT valid JSON.", e); + log.debug("SL2.0 msg: " + sl20Result); + throw new SL20Exception("sl20.02", + new Object[] {"SL2.0 command or result is NOT valid JSON."}, e); + + } + + // check on errorMessage + final VerificationResult payLoadContainerErrorCheck = + SL20JsonExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, false); + if (SL20JsonExtractorUtils + .getStringValue(payLoadContainerErrorCheck.getPayload(), + SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) + .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { + log.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR + " result .... "); + final JsonNode errorResult = SL20JsonExtractorUtils + .extractSL20Result(payLoadContainerErrorCheck.getPayload(), joseTools, false); + final String errorCode = SL20JsonExtractorUtils.getStringValue(errorResult, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true); + final String errorMsg = SL20JsonExtractorUtils.getStringValue(errorResult, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, false); + + log.info("Receiving errorcode: {} with msg: {} from VDA! Stopping auth-process ... ", + errorCode, errorMsg); + // aTrustErrorWorkAround = true; + throw new SL20Exception("sl20.08", new Object[] {errorCode, errorMsg}); + + } else { + // Receive no error - To request validation + + // validate reqId with inResponseTo + final String sl20ReqId = pendingReq.getRawData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class); + final String inRespTo = + SL20JsonExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true); + if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { + log.info( + "SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + throw new SL20SecurityException( + "SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + } + + + // validate signature + final VerificationResult payLoadContainer = SL20JsonExtractorUtils + .extractSL20PayLoad(sl20ReqObj, joseTools, authConfig.getBasicConfigurationBoolean( + Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)); + + if ((payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned())) { + if (authConfig.getBasicConfigurationBoolean( + Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)) { + log.info("SL20 result from VDA was not valid signed"); + throw new SL20SecurityException(new Object[] {"Signature on SL20 result NOT valid."}); + + } else { + log.warn( + "SL20 result from VDA is NOT valid signed, but signatures-verification " + + "is DISABLED by configuration!"); + + } + } + + payLoadContainer.getCertChain(); + + + // extract payloaf + final JsonNode payLoad = payLoadContainer.getPayload(); + + + // handle SL2.0 response payLoad + handleResponsePayLoad(payLoad); + + } + + } catch (final EaafAuthenticationException e) { + log.warn("SL2.0 processing error:", e); + if (sl20Result != null) { + log.debug("Received SL2.0 result: " + sl20Result); + } + pendingReq.setRawDataToTransaction( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, + new TaskExecutionException(pendingReq, + "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e)); + + } catch (final Exception e) { + log.warn("ERROR:", e); + log.warn("SL2.0 Authentication FAILED with a generic error.", e); + if (sl20Result != null) { + log.debug("Received SL2.0 result: " + sl20Result); + } + pendingReq.setRawDataToTransaction( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, + new TaskExecutionException(pendingReq, e.getMessage(), e)); + + } finally { + // store pending request + requestStoreage.storePendingRequest(pendingReq); + + // write SL2.0 response + if (sl20ReqObj != null) { + // buildResponse(request, response, sl20ReqObj, aTrustErrorWorkAround); + buildResponse(request, response, sl20ReqObj); + } else { + buildErrorResponse(request, response, "2000", "General transport Binding error"); + } + + } + + } catch (final Exception e) { + // write internal server errror 500 according to SL2.0 specification, chapter https transport + // binding + log.warn("Can NOT build SL2.0 response. Reason: " + e.getMessage(), e); + if (sl20Result != null) { + log.debug("Received SL2.0 result: " + sl20Result); + } + try { + response.sendError(500, "Internal Server Error."); + + } catch (final IOException e1) { + log.error("Can NOT send error message. SOMETHING IS REALY WRONG!", e); + + } + + } finally { + TransactionIdUtils.removeTransactionId(); + TransactionIdUtils.removeSessionId(); + + } + } + + protected abstract void handleResponsePayLoad(JsonNode payLoad) + throws SlCommandoParserException, SL20Exception, EaafStorageException; + + protected abstract String getResumeEndPoint(); + + private void buildErrorResponse(final HttpServletRequest request, + final HttpServletResponse response, final String errorCode, final String errorMsg) + throws Exception { + final ObjectNode error = SL20JsonBuilderUtils.createErrorCommandResult(errorCode, errorMsg); + final ObjectNode errorCommand = SL20JsonBuilderUtils + .createCommandResponse(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, error, null); + + + final ObjectNode respContainer = SL20JsonBuilderUtils + .createGenericResponse(UUID.randomUUID().toString(), null, null, errorCommand, null); + + log.trace("SL20 response to VDA: " + respContainer); + final StringWriter writer = new StringWriter(); + writer.write(respContainer.toString()); + final byte[] content = writer.toString().getBytes("UTF-8"); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentLength(content.length); + response.setContentType(ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(content); + + } + + private void buildResponse(final HttpServletRequest request, final HttpServletResponse response, + final JsonNode sl20ReqObj) throws IOException, SL20Exception, URISyntaxException { + // create response + final Map<String, String> reqParameters = new HashMap<>(); + reqParameters.put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, + pendingReq.getPendingRequestId()); + final ObjectNode callReqParams = SL20JsonBuilderUtils.createCallCommandParameters( + new DataUrlBuilder().buildDataUrl(pendingReq.getAuthUrl(), getResumeEndPoint(), null), + SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET, false, reqParameters); + final ObjectNode callCommand = SL20JsonBuilderUtils + .createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams); + + // build first redirect command for app + final ObjectNode redirectOneParams = SL20JsonBuilderUtils.createRedirectCommandParameters( + generateIpcRedirectUrlForDebugging(), callCommand, null, true); + final ObjectNode redirectOneCommand = SL20JsonBuilderUtils + .createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams); + + // build second redirect command for IDP + final ObjectNode redirectTwoParams = SL20JsonBuilderUtils.createRedirectCommandParameters( + new DataUrlBuilder().buildDataUrl(pendingReq.getAuthUrl(), getResumeEndPoint(), + pendingReq.getPendingRequestId()), + redirectOneCommand, null, false); + final ObjectNode redirectTwoCommand = SL20JsonBuilderUtils + .createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams); + + // build generic SL2.0 response container + final String transactionId = + SL20JsonExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); + final ObjectNode respContainer = SL20JsonBuilderUtils.createGenericRequest( + UUID.randomUUID().toString(), transactionId, redirectTwoCommand, null); + + if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null + && request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) + .equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { + log.debug("Client request containts 'native client' header ... "); + log.trace("SL20 response to VDA: " + respContainer); + final StringWriter writer = new StringWriter(); + writer.write(respContainer.toString()); + final byte[] content = writer.toString().getBytes("UTF-8"); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentLength(content.length); + response.setContentType(ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(content); + + + } else { + log.info("SL2.0 DataURL communication needs http header: '" + + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"); + + log.debug("Client request containts is no native client ... "); + final URIBuilder clientRedirectUri = + new URIBuilder(new DataUrlBuilder().buildDataUrl(pendingReq.getAuthUrl(), + getResumeEndPoint(), pendingReq.getPendingRequestId())); + response.setStatus(Integer + .parseInt(authConfig.getBasicConfiguration(Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, + Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); + response.setHeader("Location", clientRedirectUri.build().toString()); + + + // throw new SL20Exception("sl20.06", + // new Object[] {"SL2.0 DataURL communication needs http header: '" + + // SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"}); + + } + } + + /** + * Generates a IPC redirect URL that is configured on IDP side. + * + * @return IPC ReturnURL, or null if no URL is configured + */ + private String generateIpcRedirectUrlForDebugging() { + + + String ipcRedirectUrlConfig = + authConfig.getBasicConfiguration(Constants.CONFIG_PROP_IPC_RETURN_URL); + if (StringUtils.isNotEmpty(ipcRedirectUrlConfig)) { + if (ipcRedirectUrlConfig.contains(PATTERN_PENDING_REQ_ID)) { + log.trace("Find 'pendingReqId' pattern in IPC redirect URL. Update url ... "); + ipcRedirectUrlConfig = ipcRedirectUrlConfig.replaceAll("#PENDINGREQID#", + EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "=" + + pendingReq.getPendingRequestId()); + + } + + return ipcRedirectUrlConfig; + } + + return null; + + } + + +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java deleted file mode 100644 index b4039cf9..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java +++ /dev/null @@ -1,321 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.tasks; - -import java.io.IOException; -import java.io.StringWriter; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.entity.ContentType; -import org.jose4j.base64url.Base64Url; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; -import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; -import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException; -import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; -import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; -import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder; -import at.gv.egiz.eaaf.core.impl.utils.StreamUtils; -import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils; -import at.gv.egiz.eaaf.modules.auth.sl20.Constants; -import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes; -import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.IJOSETools; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.JsonMapper; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONBuilderUtils; -import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONExtractorUtils; - - -public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(AbstractReceiveQualeIDTask.class); - - @Autowired(required=true) private IJOSETools joseTools; - - @Override - public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { - String sl20Result = null; - - try { - log.debug("Receiving SL2.0 response process .... "); - JsonNode sl20ReqObj = null; - - //A-Trust does not SET http-header 'SL2ClientType' with value 'native' - //If A-trust sends an error, its maybe FrontChannel on DataURL - //boolean aTrustErrorWorkAround = false; - - try { - //get SL2.0 command or result from HTTP request - final Map<String, String> reqParams = getParameters(request); - sl20Result = reqParams.get(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM); - - if (StringUtils.isEmpty(sl20Result)) { - //Workaround for SIC Handy-Signature, because it sends result in InputStream - final String isReqInput = StreamUtils.readStream(request.getInputStream(), "UTF-8"); - if (StringUtils.isNotEmpty(isReqInput)) { - log.info("Use SIC Handy-Signature work-around!"); - sl20Result = isReqInput.substring("slcommand=".length()); - - } else { - log.info("NO SL2.0 commando or result FOUND."); - throw new SL20Exception("sl20.04", null); - } - - } - - log.trace("Received SL2.0 result: " + sl20Result); - revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_DATAURL_IP, request.getRemoteAddr()); - - //parse SL2.0 command/result into JSON - try { - sl20ReqObj = new JsonMapper().getMapper().readTree(Base64Url.decodeToUtf8String(sl20Result)); - - } catch (final JsonParseException e) { - log.warn("SL2.0 command or result is NOT valid JSON.", e); - log.debug("SL2.0 msg: " + sl20Result); - throw new SL20Exception("sl20.02", new Object[]{"SL2.0 command or result is NOT valid JSON."}, e); - - } - - //check on errorMessage - final VerificationResult payLoadContainerErrorCheck = SL20JSONExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, false); - if (SL20JSONExtractorUtils.getStringValue( - payLoadContainerErrorCheck.getPayload(), SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) - .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { - log.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR + " result .... "); - final JsonNode errorResult = SL20JSONExtractorUtils.extractSL20Result(payLoadContainerErrorCheck.getPayload(), joseTools, false); - final String errorCode = SL20JSONExtractorUtils.getStringValue(errorResult, - SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true); - final String errorMsg = SL20JSONExtractorUtils.getStringValue(errorResult, - SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, false); - - log.info("Receiving errorcode: {} with msg: {} from VDA! Stopping auth-process ... ", errorCode, errorMsg); - //aTrustErrorWorkAround = true; - throw new SL20Exception("sl20.08", new Object[] {errorCode, errorMsg}); - - } else { - //Receive no error - To request validation - - //validate reqId with inResponseTo - final String sl20ReqId = pendingReq.getRawData(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class); - final String inRespTo = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true); - if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { - log.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); - throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); - } - - - //validate signature - final VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad( - sl20ReqObj, joseTools, - authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)); - - if ( (payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned())) { - if (authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)) { - log.info("SL20 result from VDA was not valid signed"); - throw new SL20SecurityException(new Object[]{"Signature on SL20 result NOT valid."}); - - } else { - log.warn("SL20 result from VDA is NOT valid signed, but signatures-verification is DISABLED by configuration!"); - - } - } - - payLoadContainer.getCertChain(); - - - //extract payloaf - final JsonNode payLoad = payLoadContainer.getPayload(); - - - //handle SL2.0 response payLoad - handleResponsePayLoad(payLoad); - - } - - } catch (final EAAFAuthenticationException e) { - log.warn("SL2.0 processing error:", e); - if (sl20Result != null) - log.debug("Received SL2.0 result: " + sl20Result); - pendingReq.setRawDataToTransaction( - Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, - new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e)); - - } catch (final Exception e) { - log.warn("ERROR:", e); - log.warn("SL2.0 Authentication FAILED with a generic error.", e); - if (sl20Result != null) - log.debug("Received SL2.0 result: " + sl20Result); - pendingReq.setRawDataToTransaction( - Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, - new TaskExecutionException(pendingReq, e.getMessage(), e)); - - } finally { - //store pending request - requestStoreage.storePendingRequest(pendingReq); - - //write SL2.0 response - if (sl20ReqObj != null) - //buildResponse(request, response, sl20ReqObj, aTrustErrorWorkAround); - buildResponse(request, response, sl20ReqObj); - else - buildErrorResponse(request, response, "2000", "General transport Binding error"); - - } - - } catch (final Exception e) { - //write internal server errror 500 according to SL2.0 specification, chapter https transport binding - log.warn("Can NOT build SL2.0 response. Reason: " + e.getMessage(), e); - if (sl20Result != null) - log.debug("Received SL2.0 result: " + sl20Result); - try { - response.sendError(500, "Internal Server Error."); - - } catch (final IOException e1) { - log.error("Can NOT send error message. SOMETHING IS REALY WRONG!", e); - - } - - } finally { - TransactionIDUtils.removeTransactionId(); - TransactionIDUtils.removeSessionId(); - - } - } - - protected abstract void handleResponsePayLoad(JsonNode payLoad) throws SLCommandoParserException, SL20Exception, EAAFStorageException; - - protected abstract String getResumeEndPoint(); - - private void buildErrorResponse(HttpServletRequest request, HttpServletResponse response, String errorCode, String errorMsg) throws Exception { - final ObjectNode error = SL20JSONBuilderUtils.createErrorCommandResult(errorCode, errorMsg); - final ObjectNode errorCommand = SL20JSONBuilderUtils.createCommandResponse(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, error, null); - - - final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericResponse( - UUID.randomUUID().toString(), - null, - null, - errorCommand , - null); - - log.trace("SL20 response to VDA: " + respContainer); - final StringWriter writer = new StringWriter(); - writer.write(respContainer.toString()); - final byte[] content = writer.toString().getBytes("UTF-8"); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentLength(content.length); - response.setContentType(ContentType.APPLICATION_JSON.toString()); - response.getOutputStream().write(content); - - } - - private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20ReqObj) throws IOException, SL20Exception, URISyntaxException { - //create response - final Map<String, String> reqParameters = new HashMap<String, String>(); - reqParameters.put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId()); - final ObjectNode callReqParams = SL20JSONBuilderUtils.createCallCommandParameters( - new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), null), - SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET, - false, - reqParameters); - final ObjectNode callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams); - - //build first redirect command for app - final ObjectNode redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters( - generateICPRedirectURLForDebugging(), - callCommand, null, true); - final ObjectNode redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams); - - //build second redirect command for IDP - final ObjectNode redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters( - new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId()), - redirectOneCommand, null, false); - final ObjectNode redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams); - - //build generic SL2.0 response container - final String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); - final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericRequest( - UUID.randomUUID().toString(), - transactionId, - redirectTwoCommand, - null); - - if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && - request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { - log.debug("Client request containts 'native client' header ... "); - log.trace("SL20 response to VDA: " + respContainer); - final StringWriter writer = new StringWriter(); - writer.write(respContainer.toString()); - final byte[] content = writer.toString().getBytes("UTF-8"); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentLength(content.length); - response.setContentType(ContentType.APPLICATION_JSON.toString()); - response.getOutputStream().write(content); - - - } else { - log.info("SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"); - - log.debug("Client request containts is no native client ... "); - final URIBuilder clientRedirectURI = new URIBuilder( - new DataURLBuilder().buildDataURL( - pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId())); - response.setStatus(Integer.parseInt( - authConfig.getBasicConfiguration( - Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, - Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); - response.setHeader("Location", clientRedirectURI.build().toString()); - - -// throw new SL20Exception("sl20.06", -// new Object[] {"SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"}); - - } - } - - /** - * Generates a IPC redirect URL that is configured on IDP side - * - * @return IPC ReturnURL, or null if no URL is configured - */ - private String generateICPRedirectURLForDebugging() { - final String PATTERN_PENDING_REQ_ID = "#PENDINGREQID#"; - - String ipcRedirectURLConfig = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_IPC_RETURN_URL); - if (StringUtils.isNotEmpty(ipcRedirectURLConfig)) { - if (ipcRedirectURLConfig.contains(PATTERN_PENDING_REQ_ID)) { - log.trace("Find 'pendingReqId' pattern in IPC redirect URL. Update url ... "); - ipcRedirectURLConfig = ipcRedirectURLConfig.replaceAll( - "#PENDINGREQID#", - EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "=" + pendingReq.getPendingRequestId()); - - } - - return ipcRedirectURLConfig; - } - - return null; - - } - - -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java deleted file mode 100644 index b124ada7..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java +++ /dev/null @@ -1,87 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.utils; - -import java.io.IOException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.cert.X509Certificate; -import java.util.List; - -import javax.annotation.Nonnull; - -import org.jose4j.jwa.AlgorithmConstraints; -import org.jose4j.lang.JoseException; - -import com.fasterxml.jackson.databind.JsonNode; - -import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException; - -public interface IJOSETools { - - /** - * Create a JWS signature - * - * @param payLoad Payload to sign - * @throws SLCommandoBuildException - */ - public String createSignature(String payLoad) throws SLCommandoBuildException; - - /** - * Validates a signed SL2.0 message - * - * @param serializedContent - * @return - * @throws SLCommandoParserException - * @throws SL20Exception - */ - @Nonnull - public VerificationResult validateSignature(@Nonnull String serializedContent) throws SL20Exception; - - /** - * Validate a JWS signature - * - * @param serializedContent JWS in serialized form - * @param trustedCerts trusted X509 certificates - * @param constraints signature verification constraints - * @return Signature-verification result - * @throws JoseException - * @throws IOException - */ - @Nonnull - public VerificationResult validateSignature(@Nonnull String serializedContent, @Nonnull List<X509Certificate> trustedCerts, - @Nonnull AlgorithmConstraints constraints) throws JoseException, IOException; - - /** - * Validate a JWS signature - * - * @param serializedContent JWS in serialized form - * @param trustStore with trusted X509 certificates - * @param algconstraints signature verification constraints - * @return Signature-verification result - * @throws JoseException - * @throws IOException - * @throws KeyStoreException - */ - @Nonnull - public VerificationResult validateSignature(@Nonnull String serializedContent, @Nonnull KeyStore trustStore, - @Nonnull AlgorithmConstraints algconstraints) throws JoseException, IOException, KeyStoreException; - - /** - * Get the encryption certificate for SL2.0 End-to-End encryption - * - * @return - */ - public X509Certificate getEncryptionCertificate(); - - /** - * Decrypt a serialized JWE token - * - * @param compactSerialization Serialized JWE token - * @return decrypted payload - * @throws SL20Exception - */ - public JsonNode decryptPayload(String compactSerialization) throws SL20Exception; - -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java new file mode 100644 index 00000000..caa2e8d8 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java @@ -0,0 +1,84 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.utils; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.X509Certificate; +import java.util.List; +import javax.annotation.Nonnull; +import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException; +import org.jose4j.jwa.AlgorithmConstraints; +import org.jose4j.lang.JoseException; +import com.fasterxml.jackson.databind.JsonNode; + +public interface IJoseTools { + + /** + * Create a JWS signature. + * + * @param payLoad Payload to sign + * @throws SlCommandoBuildException In case of a signature creation error + */ + public String createSignature(String payLoad) throws SlCommandoBuildException; + + /** + * Validates a signed SL2.0 message. + * + * @param serializedContent Serialized JWS signature + * @return Verification-result DAO + * @throws SL20Exception In case of a signature validation error + */ + @Nonnull + public VerificationResult validateSignature(@Nonnull String serializedContent) + throws SL20Exception; + + /** + * Validate a JWS signature. + * + * @param serializedContent JWS in serialized form + * @param trustedCerts trusted X509 certificates + * @param constraints signature verification constraints + * @return Signature-verification result + * @throws JoseException In case of a signature verification error + * @throws IOException In case of a general IO error + */ + @Nonnull + public VerificationResult validateSignature(@Nonnull String serializedContent, + @Nonnull List<X509Certificate> trustedCerts, @Nonnull AlgorithmConstraints constraints) + throws JoseException, IOException; + + /** + * Validate a JWS signature. + * + * @param serializedContent JWS in serialized form + * @param trustStore with trusted X509 certificates + * @param algconstraints signature verification constraints + * @return Signature-verification result + * @throws JoseException In case of a signature verification error + * @throws IOException In case of a general IO error + * @throws KeyStoreException In case of TrustStore error + */ + @Nonnull + public VerificationResult validateSignature(@Nonnull String serializedContent, + @Nonnull KeyStore trustStore, @Nonnull AlgorithmConstraints algconstraints) + throws JoseException, IOException, KeyStoreException; + + /** + * Get the encryption certificate for SL2.0 End-to-End encryption. + * + * @return + */ + public X509Certificate getEncryptionCertificate(); + + /** + * Decrypt a serialized JWE token. + * + * @param compactSerialization Serialized JWE token + * @return decrypted payload + * @throws SL20Exception In case of a decryption error + */ + public JsonNode decryptPayload(String compactSerialization) throws SL20Exception; + +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java index b33649e1..f38203d2 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java @@ -18,114 +18,125 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.TypeFactory; import at.gv.egiz.eaaf.core.api.utils.IJsonMapper; -import at.gv.egiz.eaaf.core.exceptions.EAAFJsonMapperException; +import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException; public class JsonMapper implements IJsonMapper { - private static final Logger log = LoggerFactory.getLogger(JsonMapper.class); - - private final ObjectMapper mapper = new ObjectMapper(); - - /** - * The default constructor where the default pretty printer is disabled. - */ - public JsonMapper() { - this(false); - - } - - /** - * The constructor. - * @param prettyPrint enables or disables the default pretty printer - */ - public JsonMapper(@NonNull boolean prettyPrint) { - log.trace("Initializing JSON object-mapper ... "); - mapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true); - mapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , true); - mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); - mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY); - mapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY); - if (prettyPrint) { - mapper.enable(SerializationFeature.INDENT_OUTPUT); - } - - log.debug("JSON object-mapper initialized"); - - } - - - /* (non-Javadoc) - * @at.gv.egiz.eaaf.core.api.utils.IJsonMapper#getMapper() - */ - public ObjectMapper getMapper() { - return mapper; - - } - - - /* (non-Javadoc) - * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#serialize(java.lang.Object) - */ - @Override - public String serialize(Object value) throws EAAFJsonMapperException { - try { - return mapper.writeValueAsString(value); - - } catch (final JsonProcessingException e) { - log.warn("JSON mapping FAILED with error: {}", e.getMessage()); - throw new EAAFJsonMapperException(e.getMessage(), e); - - } - - } - - /* (non-Javadoc) - * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#deserialize(java.lang.String, java.lang.Class) - */ - @Override - public <T> Object deserialize(String value, Class<T> clazz) throws EAAFJsonMapperException { - try { - if (clazz != null) { - if (clazz.isAssignableFrom(TypeReference.class)) - return mapper.readValue(value, clazz); - else { - final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); - return mapper.readValue(value, javaType); - - } - - } else - return mapper.readValue(value, Object.class); - - } catch (final IOException e) { - log.warn("JSON mapping FAILED with error: {}", e.getMessage()); - throw new EAAFJsonMapperException(e.getMessage(), e); - - } - - } - - @Override - public <T> Object deserialize(InputStream is, Class<T> clazz) throws EAAFJsonMapperException { - try { - if (clazz != null) { - if (clazz.isAssignableFrom(TypeReference.class)) - return mapper.readValue(is, clazz); - else { - final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); - return mapper.readValue(is, javaType); - - } - - } else - return mapper.readValue(is, Object.class); - - } catch (final IOException e) { - log.warn("JSON mapping FAILED with error: {}", e.getMessage()); - throw new EAAFJsonMapperException(e.getMessage(), e); - - } - - } - + private static final Logger log = LoggerFactory.getLogger(JsonMapper.class); + + private final ObjectMapper mapper = new ObjectMapper(); + + /** + * The default constructor where the default pretty printer is disabled. + */ + public JsonMapper() { + this(false); + + } + + /** + * The constructor. + * + * @param prettyPrint enables or disables the default pretty printer + */ + public JsonMapper(@NonNull final boolean prettyPrint) { + log.trace("Initializing JSON object-mapper ... "); + mapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true); + mapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); + mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); + mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY); + mapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY); + if (prettyPrint) { + mapper.enable(SerializationFeature.INDENT_OUTPUT); + } + + log.debug("JSON object-mapper initialized"); + + } + + + /* + * (non-Javadoc) + * + * @at.gv.egiz.eaaf.core.api.utils.IJsonMapper#getMapper() + */ + public ObjectMapper getMapper() { + return mapper; + + } + + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#serialize(java.lang.Object) + */ + @Override + public String serialize(final Object value) throws EaafJsonMapperException { + try { + return mapper.writeValueAsString(value); + + } catch (final JsonProcessingException e) { + log.warn("JSON mapping FAILED with error: {}", e.getMessage()); + throw new EaafJsonMapperException(e.getMessage(), e); + + } + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#deserialize(java.lang.String, java.lang.Class) + */ + @Override + public <T> Object deserialize(final String value, final Class<T> clazz) + throws EaafJsonMapperException { + try { + if (clazz != null) { + if (clazz.isAssignableFrom(TypeReference.class)) { + return mapper.readValue(value, clazz); + } else { + final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); + return mapper.readValue(value, javaType); + + } + + } else { + return mapper.readValue(value, Object.class); + } + + } catch (final IOException e) { + log.warn("JSON mapping FAILED with error: {}", e.getMessage()); + throw new EaafJsonMapperException(e.getMessage(), e); + + } + + } + + @Override + public <T> Object deserialize(final InputStream is, final Class<T> clazz) + throws EaafJsonMapperException { + try { + if (clazz != null) { + if (clazz.isAssignableFrom(TypeReference.class)) { + return mapper.readValue(is, clazz); + } else { + final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); + return mapper.readValue(is, javaType); + + } + + } else { + return mapper.readValue(is, Object.class); + } + + } catch (final IOException e) { + log.warn("JSON mapping FAILED with error: {}", e.getMessage()); + throw new EaafJsonMapperException(e.getMessage(), e); + + } + + } + } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java index c07c6081..28106377 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java @@ -38,7 +38,7 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonNode; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.FileUtils; import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; import at.gv.egiz.eaaf.core.impl.utils.X509Utils; @@ -46,375 +46,408 @@ import at.gv.egiz.eaaf.modules.auth.sl20.Constants; import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; @Service -public class JsonSecurityUtils implements IJOSETools{ - private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class); - - @Autowired(required=true) IConfiguration authConfig; - private Key signPrivKey = null; - private X509Certificate[] signCertChain = null; - - private Key encPrivKey = null; - private X509Certificate[] encCertChain = null; - - private List<X509Certificate> trustedCerts = new ArrayList<X509Certificate>(); - - private static JsonMapper mapper = new JsonMapper(); - - @PostConstruct - protected void initalize() { - log.info("Initialize SL2.0 authentication security constrains ... "); - try { - if (getKeyStoreFilePath() != null) { - final KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), - getKeyStorePassword()); - - //load signing key - signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray()); - final Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias()); - signCertChain = new X509Certificate[certChainSigning.length]; - for (int i=0; i<certChainSigning.length; i++) { - if (certChainSigning[i] instanceof X509Certificate) { - signCertChain[i] = (X509Certificate)certChainSigning[i]; - } else - log.warn("NO X509 certificate for signing: " + certChainSigning[i].getType()); - - } - - //load encryption key - try { - encPrivKey = keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray()); - if (encPrivKey != null) { - final Certificate[] certChainEncryption = keyStore.getCertificateChain(getEncryptionKeyAlias()); - encCertChain = new X509Certificate[certChainEncryption.length]; - for (int i=0; i<certChainEncryption.length; i++) { - if (certChainEncryption[i] instanceof X509Certificate) { - encCertChain[i] = (X509Certificate)certChainEncryption[i]; - } else - log.warn("NO X509 certificate for encryption: " + certChainEncryption[i].getType()); - } - } else - log.info("No encryption key for SL2.0 found. End-to-End encryption is not used."); - - } catch (final Exception e) { - log.warn("No encryption key for SL2.0 found. End-to-End encryption is not used. Reason: " + e.getMessage(), e); - - } - - //load trusted certificates - trustedCerts = readCertsFromKeyStore(keyStore); - - //some short validation - if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) { - log.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); - throw new SL20Exception("sl20.03", new Object[]{"Can NOT open private key for signing"}); - - } - - if (signCertChain == null || signCertChain.length == 0) { - log.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); - throw new SL20Exception("sl20.03", new Object[]{"NO certificate for SL2.0 signing"}); - - } - - log.info("SL2.0 authentication security constrains initialized."); - - } else - log.info("NO SL2.0 authentication security configuration. Initialization was skipped"); - - } catch ( final Exception e) { - log.error("SL2.0 security constrains initialization FAILED.", e); - - } - - } - - @Override - public String createSignature(String payLoad) throws SLCommandoBuildException { - try { - final JsonWebSignature jws = new JsonWebSignature(); - - //set payload - jws.setPayload(payLoad); - - //set basic header - jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND); - - //set signing information - jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); - jws.setKey(signPrivKey); - - //TODO: - jws.setCertificateChainHeaderValue(signCertChain); - jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]); - - return jws.getCompactSerialization(); - - } catch (final JoseException e) { - log.warn("Can NOT sign SL2.0 command.", e); - throw new SLCommandoBuildException("Can NOT sign SL2.0 command.", e); - - } - - } - - @Override - public VerificationResult validateSignature(String serializedContent, KeyStore trustStore, - AlgorithmConstraints algconstraints) throws JoseException, IOException, KeyStoreException { - final List<X509Certificate> trustedCertificates = readCertsFromKeyStore(trustStore); - return validateSignature(serializedContent, trustedCertificates , algconstraints); - - } - - @Override - @NonNull - public VerificationResult validateSignature(@Nonnull String serializedContent, @Nonnull List<X509Certificate> trustedCerts, @Nonnull AlgorithmConstraints constraints) throws JoseException, IOException { - final JsonWebSignature jws = new JsonWebSignature(); - //set payload - jws.setCompactSerialization(serializedContent); - - //set security constrains - jws.setAlgorithmConstraints(constraints); - - //load signinc certs - Key selectedKey = null; - final List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue(); - final String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue(); - if (x5cCerts != null) { - log.debug("Found x509 certificate in JOSE header ... "); - log.trace("Sorting received X509 certificates ... "); - final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); - - if (trustedCerts.contains(sortedX5cCerts.get(0))) { - selectedKey = sortedX5cCerts.get(0).getPublicKey(); - - } else { - log.info("Can NOT find JOSE certificate in truststore."); - try { - log.debug("Cert: " + Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded())); - - } catch (final CertificateEncodingException e) { - e.printStackTrace(); - - } - - } - - } else if (StringUtils.isNotEmpty(x5t256)) { - log.debug("Found x5t256 fingerprint in JOSE header .... "); - final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts); - selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList()); - - } else { - throw new JoseException("JWS contains NO signature certificate or NO certificate fingerprint"); - - } - - if (selectedKey == null) { - throw new JoseException("Can NOT select verification key for JWS. Signature verification FAILED"); - - } - - //set verification key - jws.setKey(selectedKey); - - //load payLoad - return new VerificationResult(mapper.getMapper().readTree(jws.getPayload()), null, jws.verifySignature()) ; - - - } - - @Override - @Nonnull - public VerificationResult validateSignature(@Nonnull String serializedContent) throws SL20Exception { - try { - final AlgorithmConstraints algConstraints = new AlgorithmConstraints(ConstraintType.WHITELIST, - SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()])); - - final VerificationResult result = validateSignature(serializedContent, trustedCerts, algConstraints); - - if (!result.isValidSigned()) { - log.info("JWS signature invalide. Stopping authentication process ..."); - log.debug("Received JWS msg: " + serializedContent); - throw new SL20SecurityException("JWS signature invalide."); - - } - - log.debug("SL2.0 commando signature validation sucessfull"); - return result; - - } catch (JoseException | JsonParseException e) { - log.warn("SL2.0 commando signature validation FAILED", e); - throw new SL20SecurityException(new Object[]{e.getMessage()}, e); - - } catch (final IOException e) { - log.warn("Decrypted SL2.0 result can not be parsed.", e); - throw new SLCommandoParserException("Decrypted SL2.0 result can not be parsed", e); - - } - - } - - - @Override - public JsonNode decryptPayload(String compactSerialization) throws SL20Exception { - try { - final JsonWebEncryption receiverJwe = new JsonWebEncryption(); - - //set security constrains - receiverJwe.setAlgorithmConstraints( - new AlgorithmConstraints(ConstraintType.WHITELIST, - SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()]))); - receiverJwe.setContentEncryptionAlgorithmConstraints( - new AlgorithmConstraints(ConstraintType.WHITELIST, - SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()]))); - - //set payload - receiverJwe.setCompactSerialization(compactSerialization); - - - //validate key from header against key from config - final List<X509Certificate> x5cCerts = receiverJwe.getCertificateChainHeaderValue(); - final String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue(); - if (x5cCerts != null) { - log.debug("Found x509 certificate in JOSE header ... "); - log.trace("Sorting received X509 certificates ... "); - final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); - - if (!sortedX5cCerts.get(0).equals(encCertChain[0])) { - log.info("Certificate from JOSE header does NOT match encryption certificate"); - log.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString()); - - try { - log.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded())); - } catch (final CertificateEncodingException e) { - e.printStackTrace(); - } - throw new SL20Exception("sl20.05", new Object[]{"Certificate from JOSE header does NOT match encryption certificate"}); - } - - } else if (StringUtils.isNotEmpty(x5t256)) { - log.debug("Found x5t256 fingerprint in JOSE header .... "); - final String certFingerPrint = X509Util.x5tS256(encCertChain[0]); - if (!certFingerPrint.equals(x5t256)) { - log.info("X5t256 from JOSE header does NOT match encryption certificate"); - log.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint); - throw new SL20Exception("sl20.05", new Object[]{"X5t256 from JOSE header does NOT match encryption certificate"}); - - } - - } else { - log.info("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint"); - throw new SLCommandoParserException("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint"); - - } - - //set key - receiverJwe.setKey(encPrivKey); - - - //decrypt payload - return mapper.getMapper().readTree(receiverJwe.getPlaintextString()); - - } catch (final JoseException e) { - log.warn("SL2.0 result decryption FAILED", e); - throw new SL20SecurityException(new Object[]{e.getMessage()}, e); - - } catch ( final JsonParseException e) { - log.warn("Decrypted SL2.0 result is NOT a valid JSON.", e); - throw new SLCommandoParserException("Decrypted SL2.0 result is NOT a valid JSON.", e); - - } catch (final IOException e) { - log.warn("Decrypted SL2.0 result can not be parsed.", e); - throw new SLCommandoParserException("Decrypted SL2.0 result can not be parsed", e); - } - - } - - - - @Override - public X509Certificate getEncryptionCertificate() { - //TODO: maybe update after SL2.0 update on encryption certificate parts - if (encCertChain !=null && encCertChain.length > 0) - return encCertChain[0]; - else - return null; - } - - private String getKeyStoreFilePath() throws EAAFConfigurationException, MalformedURLException { - return FileUtils.makeAbsoluteURL( - authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH), - authConfig.getConfigurationRootDirectory()); - } - - private String getKeyStorePassword() { - String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD); - if (value != null) - value = value.trim(); - - return value; - - } - - private String getSigningKeyAlias() { - String value = authConfig.getBasicConfiguration( - Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS).trim(); - if (value != null) - value = value.trim(); - - return value; - } - - private String getSigningKeyPassword() { - String value = authConfig.getBasicConfiguration( - Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD).trim(); - if (value != null) - value = value.trim(); - - return value; - } - - private String getEncryptionKeyAlias() { - String value = authConfig.getBasicConfiguration( - Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS).trim(); - if (value != null) - value = value.trim(); - - return value; - } - - private String getEncryptionKeyPassword() { - String value = authConfig.getBasicConfiguration( - Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD).trim(); - if (value != null) - value = value.trim(); - - return value; - } - - @Nonnull - private List<X509Certificate> readCertsFromKeyStore(@Nonnull KeyStore keyStore) throws KeyStoreException { - final List<X509Certificate> result = new ArrayList<>(); - - final Enumeration<String> aliases = keyStore.aliases(); - while(aliases.hasMoreElements()) { - final String el = aliases.nextElement(); - log.trace("Process TrustStoreEntry: " + el); - if (keyStore.isCertificateEntry(el)) { - final Certificate cert = keyStore.getCertificate(el); - if (cert != null && cert instanceof X509Certificate) - result.add((X509Certificate) cert); - else - log.info("Can not process entry: " + el + ". Reason: " + cert.toString()); - - } - } - - return Collections.unmodifiableList(result); - } - +public class JsonSecurityUtils implements IJoseTools { + private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class); + + @Autowired(required = true) + IConfiguration authConfig; + private Key signPrivKey = null; + private X509Certificate[] signCertChain = null; + + private Key encPrivKey = null; + private X509Certificate[] encCertChain = null; + + private List<X509Certificate> trustedCerts = new ArrayList<>(); + + private static JsonMapper mapper = new JsonMapper(); + + @PostConstruct + protected void initalize() { + log.info("Initialize SL2.0 authentication security constrains ... "); + try { + if (getKeyStoreFilePath() != null) { + final KeyStore keyStore = + KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword()); + + // load signing key + signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray()); + final Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias()); + signCertChain = new X509Certificate[certChainSigning.length]; + for (int i = 0; i < certChainSigning.length; i++) { + if (certChainSigning[i] instanceof X509Certificate) { + signCertChain[i] = (X509Certificate) certChainSigning[i]; + } else { + log.warn("NO X509 certificate for signing: " + certChainSigning[i].getType()); + } + + } + + // load encryption key + try { + encPrivKey = + keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray()); + if (encPrivKey != null) { + final Certificate[] certChainEncryption = + keyStore.getCertificateChain(getEncryptionKeyAlias()); + encCertChain = new X509Certificate[certChainEncryption.length]; + for (int i = 0; i < certChainEncryption.length; i++) { + if (certChainEncryption[i] instanceof X509Certificate) { + encCertChain[i] = (X509Certificate) certChainEncryption[i]; + } else { + log.warn("NO X509 certificate for encryption: " + certChainEncryption[i].getType()); + } + } + } else { + log.info("No encryption key for SL2.0 found. End-to-End encryption is not used."); + } + + } catch (final Exception e) { + log.warn("No encryption key for SL2.0 found. End-to-End encryption is not used. Reason: " + + e.getMessage(), e); + + } + + // load trusted certificates + trustedCerts = readCertsFromKeyStore(keyStore); + + // some short validation + if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) { + log.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); + throw new SL20Exception("sl20.03", new Object[] {"Can NOT open private key for signing"}); + + } + + if (signCertChain == null || signCertChain.length == 0) { + log.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); + throw new SL20Exception("sl20.03", new Object[] {"NO certificate for SL2.0 signing"}); + + } + + log.info("SL2.0 authentication security constrains initialized."); + + } else { + log.info("NO SL2.0 authentication security configuration. Initialization was skipped"); + } + + } catch (final Exception e) { + log.error("SL2.0 security constrains initialization FAILED.", e); + + } + + } + + @Override + public String createSignature(final String payLoad) throws SlCommandoBuildException { + try { + final JsonWebSignature jws = new JsonWebSignature(); + + // set payload + jws.setPayload(payLoad); + + // set basic header + jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND); + + // set signing information + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); + jws.setKey(signPrivKey); + + // TODO: + jws.setCertificateChainHeaderValue(signCertChain); + jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]); + + return jws.getCompactSerialization(); + + } catch (final JoseException e) { + log.warn("Can NOT sign SL2.0 command.", e); + throw new SlCommandoBuildException("Can NOT sign SL2.0 command.", e); + + } + + } + + @Override + public VerificationResult validateSignature(final String serializedContent, + final KeyStore trustStore, final AlgorithmConstraints algconstraints) + throws JoseException, IOException, KeyStoreException { + final List<X509Certificate> trustedCertificates = readCertsFromKeyStore(trustStore); + return validateSignature(serializedContent, trustedCertificates, algconstraints); + + } + + @Override + @NonNull + public VerificationResult validateSignature(@Nonnull final String serializedContent, + @Nonnull final List<X509Certificate> trustedCerts, + @Nonnull final AlgorithmConstraints constraints) throws JoseException, IOException { + final JsonWebSignature jws = new JsonWebSignature(); + // set payload + jws.setCompactSerialization(serializedContent); + + // set security constrains + jws.setAlgorithmConstraints(constraints); + + // load signinc certs + Key selectedKey = null; + final List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue(); + final String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue(); + if (x5cCerts != null) { + log.debug("Found x509 certificate in JOSE header ... "); + log.trace("Sorting received X509 certificates ... "); + final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + + if (trustedCerts.contains(sortedX5cCerts.get(0))) { + selectedKey = sortedX5cCerts.get(0).getPublicKey(); + + } else { + log.info("Can NOT find JOSE certificate in truststore."); + try { + log.debug("Cert: " + Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded())); + + } catch (final CertificateEncodingException e) { + e.printStackTrace(); + + } + + } + + } else if (StringUtils.isNotEmpty(x5t256)) { + log.debug("Found x5t256 fingerprint in JOSE header .... "); + final X509VerificationKeyResolver x509VerificationKeyResolver = + new X509VerificationKeyResolver(trustedCerts); + selectedKey = + x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList()); + + } else { + throw new JoseException( + "JWS contains NO signature certificate or NO certificate fingerprint"); + + } + + if (selectedKey == null) { + throw new JoseException( + "Can NOT select verification key for JWS. Signature verification FAILED"); + + } + + // set verification key + jws.setKey(selectedKey); + + // load payLoad + return new VerificationResult(mapper.getMapper().readTree(jws.getPayload()), null, + jws.verifySignature()); + + + } + + @Override + @Nonnull + public VerificationResult validateSignature(@Nonnull final String serializedContent) + throws SL20Exception { + try { + final AlgorithmConstraints algConstraints = new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING + .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()])); + + final VerificationResult result = + validateSignature(serializedContent, trustedCerts, algConstraints); + + if (!result.isValidSigned()) { + log.info("JWS signature invalide. Stopping authentication process ..."); + log.debug("Received JWS msg: " + serializedContent); + throw new SL20SecurityException("JWS signature invalide."); + + } + + log.debug("SL2.0 commando signature validation sucessfull"); + return result; + + } catch (JoseException | JsonParseException e) { + log.warn("SL2.0 commando signature validation FAILED", e); + throw new SL20SecurityException(new Object[] {e.getMessage()}, e); + + } catch (final IOException e) { + log.warn("Decrypted SL2.0 result can not be parsed.", e); + throw new SlCommandoParserException("Decrypted SL2.0 result can not be parsed", e); + + } + + } + + + @Override + public JsonNode decryptPayload(final String compactSerialization) throws SL20Exception { + try { + final JsonWebEncryption receiverJwe = new JsonWebEncryption(); + + // set security constrains + receiverJwe.setAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION + .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()]))); + receiverJwe.setContentEncryptionAlgorithmConstraints(new AlgorithmConstraints( + ConstraintType.WHITELIST, SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION + .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()]))); + + // set payload + receiverJwe.setCompactSerialization(compactSerialization); + + + // validate key from header against key from config + final List<X509Certificate> x5cCerts = receiverJwe.getCertificateChainHeaderValue(); + final String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue(); + if (x5cCerts != null) { + log.debug("Found x509 certificate in JOSE header ... "); + log.trace("Sorting received X509 certificates ... "); + final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + + if (!sortedX5cCerts.get(0).equals(encCertChain[0])) { + log.info("Certificate from JOSE header does NOT match encryption certificate"); + log.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString()); + + try { + log.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded())); + } catch (final CertificateEncodingException e) { + e.printStackTrace(); + } + throw new SL20Exception("sl20.05", + new Object[] {"Certificate from JOSE header does NOT match encryption certificate"}); + } + + } else if (StringUtils.isNotEmpty(x5t256)) { + log.debug("Found x5t256 fingerprint in JOSE header .... "); + final String certFingerPrint = X509Util.x5tS256(encCertChain[0]); + if (!certFingerPrint.equals(x5t256)) { + log.info("X5t256 from JOSE header does NOT match encryption certificate"); + log.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint); + throw new SL20Exception("sl20.05", + new Object[] {"X5t256 from JOSE header does NOT match encryption certificate"}); + + } + + } else { + log.info( + "Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint"); + throw new SlCommandoParserException( + "Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint"); + + } + + // set key + receiverJwe.setKey(encPrivKey); + + + // decrypt payload + return mapper.getMapper().readTree(receiverJwe.getPlaintextString()); + + } catch (final JoseException e) { + log.warn("SL2.0 result decryption FAILED", e); + throw new SL20SecurityException(new Object[] {e.getMessage()}, e); + + } catch (final JsonParseException e) { + log.warn("Decrypted SL2.0 result is NOT a valid JSON.", e); + throw new SlCommandoParserException("Decrypted SL2.0 result is NOT a valid JSON.", e); + + } catch (final IOException e) { + log.warn("Decrypted SL2.0 result can not be parsed.", e); + throw new SlCommandoParserException("Decrypted SL2.0 result can not be parsed", e); + } + + } + + + + @Override + public X509Certificate getEncryptionCertificate() { + // TODO: maybe update after SL2.0 update on encryption certificate parts + if (encCertChain != null && encCertChain.length > 0) { + return encCertChain[0]; + } else { + return null; + } + } + + private String getKeyStoreFilePath() throws EaafConfigurationException, MalformedURLException { + return FileUtils.makeAbsoluteUrl( + authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH), + authConfig.getConfigurationRootDirectory()); + } + + private String getKeyStorePassword() { + String value = + authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD); + if (value != null) { + value = value.trim(); + } + + return value; + + } + + private String getSigningKeyAlias() { + String value = authConfig + .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS).trim(); + if (value != null) { + value = value.trim(); + } + + return value; + } + + private String getSigningKeyPassword() { + String value = authConfig + .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD).trim(); + if (value != null) { + value = value.trim(); + } + + return value; + } + + private String getEncryptionKeyAlias() { + String value = authConfig + .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS).trim(); + if (value != null) { + value = value.trim(); + } + + return value; + } + + private String getEncryptionKeyPassword() { + String value = authConfig + .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD) + .trim(); + if (value != null) { + value = value.trim(); + } + + return value; + } + + @Nonnull + private List<X509Certificate> readCertsFromKeyStore(@Nonnull final KeyStore keyStore) + throws KeyStoreException { + final List<X509Certificate> result = new ArrayList<>(); + + final Enumeration<String> aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) { + final String el = aliases.nextElement(); + log.trace("Process TrustStoreEntry: " + el); + if (keyStore.isCertificateEntry(el)) { + final Certificate cert = keyStore.getCertificate(el); + if (cert != null && cert instanceof X509Certificate) { + result.add((X509Certificate) cert); + } else { + log.info("Can not process entry: " + el + ". Reason: " + cert.toString()); + } + + } + } + + return Collections.unmodifiableList(result); + } + } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java index 06c36cff..5a8be243 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java @@ -8,234 +8,273 @@ import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers; import org.jose4j.jws.AlgorithmIdentifiers; public class SL20Constants { - public static final int CURRENT_SL20_VERSION = 10; - - //http binding parameters - public static final String PARAM_SL20_REQ_COMMAND_PARAM = "slcommand"; - public static final String PARAM_SL20_REQ_COMMAND_PARAM_OLD = "sl2command"; - - public static final String PARAM_SL20_REQ_ICP_RETURN_URL_PARAM = "slIPCReturnUrl"; - public static final String PARAM_SL20_REQ_TRANSACTIONID = "slTransactionID"; - - public static final String HTTP_HEADER_SL20_CLIENT_TYPE = "SL2ClientType"; - public static final String HTTP_HEADER_SL20_VDA_TYPE = "X-MOA-VDA"; - public static final String HTTP_HEADER_VALUE_NATIVE = "nativeApp"; - - public static final String HTTP_HEADER_SL20_RESP = "X-SL20Operation"; - - - //******************************************************************************************* - //JSON signing and encryption headers - public static final String JSON_ALGORITHM = "alg"; - public static final String JSON_CONTENTTYPE = "cty"; - public static final String JSON_X509_CERTIFICATE = "x5c"; - public static final String JSON_X509_FINGERPRINT = "x5t#S256"; - public static final String JSON_ENCRYPTION_PAYLOAD = "enc"; - - public static final String JSON_ALGORITHM_SIGNING_RS256 = AlgorithmIdentifiers.RSA_USING_SHA256; - public static final String JSON_ALGORITHM_SIGNING_RS512 = AlgorithmIdentifiers.RSA_USING_SHA512; - public static final String JSON_ALGORITHM_SIGNING_ES256 = AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256; - public static final String JSON_ALGORITHM_SIGNING_ES512 = AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512; - public static final String JSON_ALGORITHM_SIGNING_PS256 = AlgorithmIdentifiers.RSA_PSS_USING_SHA256; - public static final String JSON_ALGORITHM_SIGNING_PS512 = AlgorithmIdentifiers.RSA_PSS_USING_SHA512; - - public static final List<String> SL20_ALGORITHM_WHITELIST_SIGNING = Arrays.asList( - JSON_ALGORITHM_SIGNING_RS256, - JSON_ALGORITHM_SIGNING_RS512, - JSON_ALGORITHM_SIGNING_ES256, - JSON_ALGORITHM_SIGNING_ES512, - JSON_ALGORITHM_SIGNING_PS256, - JSON_ALGORITHM_SIGNING_PS512 - ); - - public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP = KeyManagementAlgorithmIdentifiers.RSA_OAEP; - public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP256 = KeyManagementAlgorithmIdentifiers.RSA_OAEP_256; - - public static final List<String> SL20_ALGORITHM_WHITELIST_KEYENCRYPTION = Arrays.asList( - JSON_ALGORITHM_ENC_KEY_RSAOAEP, - JSON_ALGORITHM_ENC_KEY_RSAOAEP256 - ); - - public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256 = ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256; - public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512 = ContentEncryptionAlgorithmIdentifiers.AES_256_CBC_HMAC_SHA_512; - public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128GCM = ContentEncryptionAlgorithmIdentifiers.AES_128_GCM; - public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256GCM = ContentEncryptionAlgorithmIdentifiers.AES_256_GCM; - - public static final List<String> SL20_ALGORITHM_WHITELIST_ENCRYPTION = Arrays.asList( - JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256, - JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512, - JSON_ALGORITHM_ENC_PAYLOAD_A128GCM, - JSON_ALGORITHM_ENC_PAYLOAD_A256GCM - ); - - - //********************************************************************************************* - //Object identifier for generic transport container - public static final String SL20_CONTENTTYPE_SIGNED_COMMAND ="application/sl2.0;command"; - public static final String SL20_CONTENTTYPE_ENCRYPTED_RESULT ="application/sl2.0;result"; - - public static final String SL20_VERSION = "v"; - public static final String SL20_REQID = "reqID"; - public static final String SL20_RESPID = "respID"; - public static final String SL20_INRESPTO = "inResponseTo"; - public static final String SL20_TRANSACTIONID = "transactionID"; - public static final String SL20_PAYLOAD = "payload"; - public static final String SL20_SIGNEDPAYLOAD = "signedPayload"; - - //Generic Object identifier for commands - public static final String SL20_COMMAND_CONTAINER_NAME = "name"; - public static final String SL20_COMMAND_CONTAINER_PARAMS = "params"; - public static final String SL20_COMMAND_CONTAINER_RESULT = "result"; - public static final String SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT = "encryptedResult"; - - //COMMAND Object identifier - public static final String SL20_COMMAND_IDENTIFIER_REDIRECT = "redirect"; - public static final String SL20_COMMAND_IDENTIFIER_CALL = "call"; - public static final String SL20_COMMAND_IDENTIFIER_ERROR = "error"; - @Deprecated public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEID = "qualifiedeID"; - public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEIDCONSENT = "qualifiedEIDConsent"; - //public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDSIG = "qualifiedSig"; - - public static final String SL20_COMMAND_IDENTIFIER_GETCERTIFICATE = "getCertificate"; - public static final String SL20_COMMAND_IDENTIFIER_CREATE_SIG_CADES = "createCAdES"; - - - public static final String SL20_COMMAND_IDENTIFIER_BINDING_CREATE_KEY = "createBindingKey"; - public static final String SL20_COMMAND_IDENTIFIER_BINDING_STORE_CERT = "storeBindingCert"; - - public static final String SL20_COMMAND_IDENTIFIER_AUTH_IDANDPASSWORD = "idAndPassword"; - public static final String SL20_COMMAND_IDENTIFIER_AUTH_JWSTOKENFACTOR = "jwsTokenAuth"; - public static final String SL20_COMMAND_IDENTIFIER_AUTH_QRCODEFACTOR = "qrCodeFactor"; - - //*****COMMAND parameter identifier****** - //general Identifier - public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_VALUE = "value"; - public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_KEY = "key"; - public static final String SL20_COMMAND_PARAM_GENERAL_DATAURL = "dataUrl"; - public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE = "x5cEnc"; - public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK = "jwkEnc"; - - //Redirect command - public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL = "url"; - public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND = "command"; - public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND = "signedCommand"; - public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT = "IPCRedirect"; - - //Call command - public static final String SL20_COMMAND_PARAM_GENERAL_CALL_URL = SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL; - public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD = "method"; - public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET = "get"; - public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_POST = "post"; - public static final String SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID = "includeTransactionID"; - public static final String SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER = "reqParams"; - - //error command - public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE = "errorCode"; - public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE = "errorMessage"; - - //qualified eID command - @Deprecated public static final String SL20_COMMAND_PARAM_EID_AUTHBLOCKID = "authBlockTemplateID"; - public static final String SL20_COMMAND_PARAM_EID_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES = "attributes"; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_MANDATEREFVALUE = "MANDATE-REFERENCE-VALUE"; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPUNIQUEID = "SP-UNIQUEID"; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPFRIENDLYNAME = "SP-FRIENDLYNAME"; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPCOUNTRYCODE = "SP-COUNTRYCODE"; - public static final String SL20_COMMAND_PARAM_EID_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; - public static final String SL20_COMMAND_PARAM_EID_JWKCENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_RESULT_IDL = "EID-IDENTITY-LINK"; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK = "EID-AUTH-BLOCK"; - public static final String SL20_COMMAND_PARAM_EID_RESULT_CCSURL = "EID-CCS-URL"; - @Deprecated public static final String SL20_COMMAND_PARAM_EID_RESULT_LOA = "EID-CITIZEN-QAA-LEVEL"; - - public static final String SL20_COMMAND_PARAM_EID_CONSENTTEMPLATEID = "consentTemplateID"; - public static final String SL20_COMMAND_PARAM_EID_CONSENT = "consent"; - public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_MDS = "MDS"; - public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_VSZ = "vSZ"; - public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_SIGNEDCONSENT = "signedConsent"; - - //qualified Signature comamnd -// public static final String SL20_COMMAND_PARAM_QUALSIG_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; -// public static final String SL20_COMMAND_PARAM_QUALSIG_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; - - - //getCertificate - public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_KEYID = "keyId"; - public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; - public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_JWKCENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; - public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_RESULT_CERTIFICATE = "x5c"; - - //createCAdES Signture - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_KEYID = "keyId"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CONTENT = "content"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_MIMETYPE = "mimeType"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_PADES_COMBATIBILTY = "padesComatibility"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_EXCLUDEBYTERANGE = "excludedByteRange"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL = "cadesLevel"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_JWKCENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_RESULT_SIGNATURE = "signature"; - - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_BASIC = "cAdES"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_T = "cAdES-T"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_C = "cAdES-C"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_X = "cAdES-X"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_XL = "cAdES-X-L"; - public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_A = "cAdES-A"; - - - - //create binding key command - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID = "kontoID"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_SN = "SN"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH = "keyLength"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG = "keyAlg"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES = "policies"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST = "x5cVdaTrust"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD = "reqUserPassword"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; - - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_RSA = "RSA"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_SECPR256R1 = "secp256r1"; - - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_LIFETIME = "lifeTime"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_USESECUREELEMENT = "useSecureElement"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_KEYTIMEOUT = "keyTimeout"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_NEEDUSERAUTH = "needUserAuth"; - - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID = "appID"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR = "csr"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE = "attCert"; - public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD = "encodedPass"; - - - //store binding certificate command - public static final String SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE = "x5c"; - public static final String SL20_COMMAND_PARAM_BINDING_STORE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS = "success"; - public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE = "OK"; - - // Username and password authentication - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG = "keyAlg"; - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PLAIN = "plain"; - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PBKDF2 = "PBKDF2"; - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID = SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID; - public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD = SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD; - - //JWS Token authentication - public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE = "nonce"; - public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA = "displayData"; - public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL = "displayUrl"; - public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE = SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE; - - //QR-Code authentication - public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_QRCODE = "qrCode"; - public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - + public static final int CURRENT_SL20_VERSION = 10; + + // http binding parameters + public static final String PARAM_SL20_REQ_COMMAND_PARAM = "slcommand"; + public static final String PARAM_SL20_REQ_COMMAND_PARAM_OLD = "sl2command"; + + public static final String PARAM_SL20_REQ_ICP_RETURN_URL_PARAM = "slIPCReturnUrl"; + public static final String PARAM_SL20_REQ_TRANSACTIONID = "slTransactionID"; + + public static final String HTTP_HEADER_SL20_CLIENT_TYPE = "SL2ClientType"; + public static final String HTTP_HEADER_SL20_VDA_TYPE = "X-MOA-VDA"; + public static final String HTTP_HEADER_VALUE_NATIVE = "nativeApp"; + + public static final String HTTP_HEADER_SL20_RESP = "X-SL20Operation"; + + + // ******************************************************************************************* + // JSON signing and encryption headers + public static final String JSON_ALGORITHM = "alg"; + public static final String JSON_CONTENTTYPE = "cty"; + public static final String JSON_X509_CERTIFICATE = "x5c"; + public static final String JSON_X509_FINGERPRINT = "x5t#S256"; + public static final String JSON_ENCRYPTION_PAYLOAD = "enc"; + + public static final String JSON_ALGORITHM_SIGNING_RS256 = AlgorithmIdentifiers.RSA_USING_SHA256; + public static final String JSON_ALGORITHM_SIGNING_RS512 = AlgorithmIdentifiers.RSA_USING_SHA512; + public static final String JSON_ALGORITHM_SIGNING_ES256 = + AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256; + public static final String JSON_ALGORITHM_SIGNING_ES512 = + AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512; + public static final String JSON_ALGORITHM_SIGNING_PS256 = + AlgorithmIdentifiers.RSA_PSS_USING_SHA256; + public static final String JSON_ALGORITHM_SIGNING_PS512 = + AlgorithmIdentifiers.RSA_PSS_USING_SHA512; + + public static final List<String> SL20_ALGORITHM_WHITELIST_SIGNING = Arrays.asList( + JSON_ALGORITHM_SIGNING_RS256, JSON_ALGORITHM_SIGNING_RS512, JSON_ALGORITHM_SIGNING_ES256, + JSON_ALGORITHM_SIGNING_ES512, JSON_ALGORITHM_SIGNING_PS256, JSON_ALGORITHM_SIGNING_PS512); + + public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP = + KeyManagementAlgorithmIdentifiers.RSA_OAEP; + public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP256 = + KeyManagementAlgorithmIdentifiers.RSA_OAEP_256; + + public static final List<String> SL20_ALGORITHM_WHITELIST_KEYENCRYPTION = + Arrays.asList(JSON_ALGORITHM_ENC_KEY_RSAOAEP, JSON_ALGORITHM_ENC_KEY_RSAOAEP256); + + public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256 = + ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256; + public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512 = + ContentEncryptionAlgorithmIdentifiers.AES_256_CBC_HMAC_SHA_512; + public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128GCM = + ContentEncryptionAlgorithmIdentifiers.AES_128_GCM; + public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256GCM = + ContentEncryptionAlgorithmIdentifiers.AES_256_GCM; + + public static final List<String> SL20_ALGORITHM_WHITELIST_ENCRYPTION = Arrays.asList( + JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256, JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512, + JSON_ALGORITHM_ENC_PAYLOAD_A128GCM, JSON_ALGORITHM_ENC_PAYLOAD_A256GCM); + + + // ********************************************************************************************* + // Object identifier for generic transport container + public static final String SL20_CONTENTTYPE_SIGNED_COMMAND = "application/sl2.0;command"; + public static final String SL20_CONTENTTYPE_ENCRYPTED_RESULT = "application/sl2.0;result"; + + public static final String SL20_VERSION = "v"; + public static final String SL20_REQID = "reqID"; + public static final String SL20_RESPID = "respID"; + public static final String SL20_INRESPTO = "inResponseTo"; + public static final String SL20_TRANSACTIONID = "transactionID"; + public static final String SL20_PAYLOAD = "payload"; + public static final String SL20_SIGNEDPAYLOAD = "signedPayload"; + + // Generic Object identifier for commands + public static final String SL20_COMMAND_CONTAINER_NAME = "name"; + public static final String SL20_COMMAND_CONTAINER_PARAMS = "params"; + public static final String SL20_COMMAND_CONTAINER_RESULT = "result"; + public static final String SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT = "encryptedResult"; + + // COMMAND Object identifier + public static final String SL20_COMMAND_IDENTIFIER_REDIRECT = "redirect"; + public static final String SL20_COMMAND_IDENTIFIER_CALL = "call"; + public static final String SL20_COMMAND_IDENTIFIER_ERROR = "error"; + @Deprecated + public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEID = "qualifiedeID"; + public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEIDCONSENT = "qualifiedEIDConsent"; + // public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDSIG = "qualifiedSig"; + + public static final String SL20_COMMAND_IDENTIFIER_GETCERTIFICATE = "getCertificate"; + public static final String SL20_COMMAND_IDENTIFIER_CREATE_SIG_CADES = "createCAdES"; + + + public static final String SL20_COMMAND_IDENTIFIER_BINDING_CREATE_KEY = "createBindingKey"; + public static final String SL20_COMMAND_IDENTIFIER_BINDING_STORE_CERT = "storeBindingCert"; + + public static final String SL20_COMMAND_IDENTIFIER_AUTH_IDANDPASSWORD = "idAndPassword"; + public static final String SL20_COMMAND_IDENTIFIER_AUTH_JWSTOKENFACTOR = "jwsTokenAuth"; + public static final String SL20_COMMAND_IDENTIFIER_AUTH_QRCODEFACTOR = "qrCodeFactor"; + + // *****COMMAND parameter identifier****** + // general Identifier + public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_VALUE = "value"; + public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_KEY = "key"; + public static final String SL20_COMMAND_PARAM_GENERAL_DATAURL = "dataUrl"; + public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE = "x5cEnc"; + public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK = "jwkEnc"; + + // Redirect command + public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL = "url"; + public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND = "command"; + public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND = "signedCommand"; + public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT = "IPCRedirect"; + + // Call command + public static final String SL20_COMMAND_PARAM_GENERAL_CALL_URL = + SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL; + public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD = "method"; + public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET = "get"; + public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_POST = "post"; + public static final String SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID = + "includeTransactionID"; + public static final String SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER = "reqParams"; + + // error command + public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE = "errorCode"; + public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE = "errorMessage"; + + // qualified eID command + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_AUTHBLOCKID = "authBlockTemplateID"; + public static final String SL20_COMMAND_PARAM_EID_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES = "attributes"; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_MANDATEREFVALUE = + "MANDATE-REFERENCE-VALUE"; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPUNIQUEID = "SP-UNIQUEID"; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPFRIENDLYNAME = "SP-FRIENDLYNAME"; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPCOUNTRYCODE = "SP-COUNTRYCODE"; + public static final String SL20_COMMAND_PARAM_EID_X5CENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; + public static final String SL20_COMMAND_PARAM_EID_JWKCENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_RESULT_IDL = "EID-IDENTITY-LINK"; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK = "EID-AUTH-BLOCK"; + public static final String SL20_COMMAND_PARAM_EID_RESULT_CCSURL = "EID-CCS-URL"; + @Deprecated + public static final String SL20_COMMAND_PARAM_EID_RESULT_LOA = "EID-CITIZEN-QAA-LEVEL"; + + public static final String SL20_COMMAND_PARAM_EID_CONSENTTEMPLATEID = "consentTemplateID"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT = "consent"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_MDS = "MDS"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_VSZ = "vSZ"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_SIGNEDCONSENT = "signedConsent"; + + // qualified Signature comamnd + // public static final String SL20_COMMAND_PARAM_QUALSIG_DATAURL = + // SL20_COMMAND_PARAM_GENERAL_DATAURL; + // public static final String SL20_COMMAND_PARAM_QUALSIG_X5CENC = + // SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; + + + // getCertificate + public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_KEYID = "keyId"; + public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_X5CENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; + public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_JWKCENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; + public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_RESULT_CERTIFICATE = "x5c"; + + // createCAdES Signture + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_KEYID = "keyId"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CONTENT = "content"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_MIMETYPE = "mimeType"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_PADES_COMBATIBILTY = + "padesComatibility"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_EXCLUDEBYTERANGE = + "excludedByteRange"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL = "cadesLevel"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_X5CENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_JWKCENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_RESULT_SIGNATURE = "signature"; + + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_BASIC = "cAdES"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_T = "cAdES-T"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_C = "cAdES-C"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_X = "cAdES-X"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_XL = "cAdES-X-L"; + public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_A = "cAdES-A"; + + + + // create binding key command + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID = "kontoID"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_SN = "SN"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH = "keyLength"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG = "keyAlg"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES = "policies"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST = "x5cVdaTrust"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD = + "reqUserPassword"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; + + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_RSA = "RSA"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_SECPR256R1 = "secp256r1"; + + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_LIFETIME = "lifeTime"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_USESECUREELEMENT = + "useSecureElement"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_KEYTIMEOUT = "keyTimeout"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_NEEDUSERAUTH = + "needUserAuth"; + + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID = "appID"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR = "csr"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE = + "attCert"; + public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD = "encodedPass"; + + + // store binding certificate command + public static final String SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE = "x5c"; + public static final String SL20_COMMAND_PARAM_BINDING_STORE_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS = "success"; + public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE = "OK"; + + // Username and password authentication + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG = "keyAlg"; + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PLAIN = "plain"; + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PBKDF2 = "PBKDF2"; + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC = + SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID = + SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID; + public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD = + SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD; + + // JWS Token authentication + public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE = "nonce"; + public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA = "displayData"; + public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL = "displayUrl"; + public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE = + SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE; + + // QR-Code authentication + public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_QRCODE = "qrCode"; + public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_DATAURL = + SL20_COMMAND_PARAM_GENERAL_DATAURL; + } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java index 4d8cabb7..be306b69 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java @@ -3,61 +3,61 @@ package at.gv.egiz.eaaf.modules.auth.sl20.utils; import java.io.IOException; import java.io.StringWriter; import java.net.URISyntaxException; - import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.apache.http.client.utils.URIBuilder; import org.jose4j.base64url.Base64Url; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; - import com.fasterxml.jackson.databind.JsonNode; public class SL20HttpBindingUtils { - private static final Logger log = LoggerFactory.getLogger(SL20HttpBindingUtils.class); - - /** - * Write SL2.0 response into http-response object - * - * @param httpReq Current http request - * @param httpResp Current http response - * @param sl20Forward SL2.0 command that should be written to response - * @param redirectURL SL2.0 redirect URL in case of SL2.0 redirect command and no native client (see SL2.0 specification) - * @param httpCodeRedirect http redirect-code in case of SL2.0 redirect command and no native client (see SL2.0 specification) - * @throws IOException - * @throws URISyntaxException - */ - public static void writeIntoResponse(@Nonnull HttpServletRequest httpReq, @Nonnull HttpServletResponse httpResp, - @Nonnull JsonNode sl20Forward, @Nullable String redirectURL, - @Nonnull int httpCodeRedirect) throws IOException, URISyntaxException { - //forward SL2.0 command - httpResp.addIntHeader(SL20Constants.HTTP_HEADER_SL20_RESP, SL20Constants.CURRENT_SL20_VERSION); - - if (httpReq.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && - httpReq.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { - log.debug("Client request containts 'native client' header ... "); - final StringWriter writer = new StringWriter(); - writer.write(sl20Forward.toString()); - final byte[] content = writer.toString().getBytes("UTF-8"); - httpResp.setStatus(HttpServletResponse.SC_OK); - httpResp.setContentLength(content.length); - httpResp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); - httpResp.getOutputStream().write(content); - - } else { - log.debug("Client request containts is no native client ... "); - final URIBuilder clientRedirectURI = new URIBuilder(redirectURL); - clientRedirectURI.addParameter( - SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, - Base64Url.encode(sl20Forward.toString().getBytes())); - httpResp.setStatus(httpCodeRedirect); - httpResp.setHeader("Location", clientRedirectURI.build().toString()); - - } - - } + private static final Logger log = LoggerFactory.getLogger(SL20HttpBindingUtils.class); + + /** + * Write SL2.0 response into http-response object + * + * @param httpReq Current http request + * @param httpResp Current http response + * @param sl20Forward SL2.0 command that should be written to response + * @param redirectUrl SL2.0 redirect URL in case of SL2.0 redirect command and no native client + * (see SL2.0 specification) + * @param httpCodeRedirect http redirect-code in case of SL2.0 redirect command and no native + * client (see SL2.0 specification) + * @throws IOException In case of an IO error + * @throws URISyntaxException In case of a wrong URL + */ + public static void writeIntoResponse(@Nonnull final HttpServletRequest httpReq, + @Nonnull final HttpServletResponse httpResp, @Nonnull final JsonNode sl20Forward, + @Nullable final String redirectUrl, @Nonnull final int httpCodeRedirect) + throws IOException, URISyntaxException { + // forward SL2.0 command + httpResp.addIntHeader(SL20Constants.HTTP_HEADER_SL20_RESP, SL20Constants.CURRENT_SL20_VERSION); + + if (httpReq.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null + && httpReq.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) + .equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { + log.debug("Client request containts 'native client' header ... "); + final StringWriter writer = new StringWriter(); + writer.write(sl20Forward.toString()); + final byte[] content = writer.toString().getBytes("UTF-8"); + httpResp.setStatus(HttpServletResponse.SC_OK); + httpResp.setContentLength(content.length); + httpResp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + httpResp.getOutputStream().write(content); + + } else { + log.debug("Client request containts is no native client ... "); + final URIBuilder clientRedirectUri = new URIBuilder(redirectUrl); + clientRedirectUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, + Base64Url.encode(sl20Forward.toString().getBytes())); + httpResp.setStatus(httpCodeRedirect); + httpResp.setHeader("Location", clientRedirectUri.build().toString()); + + } + + } } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java deleted file mode 100644 index ba069ac7..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java +++ /dev/null @@ -1,640 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.utils; - -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Base64; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import at.gv.egiz.eaaf.modules.auth.sl20.Constants; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException; - -public class SL20JSONBuilderUtils { - - private static JsonMapper mapper = new JsonMapper(); - - /** - * Create command request - * @param name - * @param params - * @throws SLCommandoBuildException - * @return - */ - public static ObjectNode createCommand(String name, ObjectNode params) throws SLCommandoBuildException { - - final ObjectNode command = mapper.getMapper().createObjectNode(); - addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); - addSingleJSONElement(command, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, params, true); - return command; - - } - - /** - * Create signed command request - * - * @param name - * @param params - * @param signer - * @return - * @throws SLCommandoBuildException - */ - public static String createSignedCommand(String name, ObjectNode params, IJOSETools signer) throws SLCommandoBuildException { - final ObjectNode command = mapper.getMapper().createObjectNode(); - addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); - addSingleJSONElement(command, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, params, true); - return signer.createSignature(command.toString()); - - } - - - /** - * Create encrypted command result - * - * @param result - * @param encrypter - * @return - * @throws SLCommandoBuildException - */ - public static String createEncryptedCommandoResult(ObjectNode result, JsonSecurityUtils encrypter) throws SLCommandoBuildException { - //TODO: add real implementation - //create header and footer - final String dummyHeader = createJsonEncryptionHeader(encrypter).toString(); - final String payLoad = result.toString(); - final String dummyFooter = createJsonSignedFooter(encrypter); - - return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "." - + Base64.getUrlEncoder().encodeToString(payLoad.getBytes()) + "." - + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes()); - - } - - - /** - * Create command result - * - * @param name - * @param result - * @param encryptedResult - * @throws SLCommandoBuildException - * @return - */ - public static ObjectNode createCommandResponse(String name, ObjectNode result, String encryptedResult) throws SLCommandoBuildException { - final ObjectNode command = mapper.getMapper().createObjectNode(); - addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); - addOnlyOnceOfTwo(command, - SL20Constants.SL20_COMMAND_CONTAINER_RESULT, SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT, - result, encryptedResult); - return command; - - } - - /** - * Create command result - * - * @param name - * @param result - * @param encryptedResult - * @throws SLCommandoBuildException - * @return - */ - public static String createSignedCommandResponse(String name, ObjectNode result, String encryptedResult, JsonSecurityUtils signer) throws SLCommandoBuildException { - final ObjectNode command = mapper.getMapper().createObjectNode(); - addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); - addOnlyOnceOfTwo(command, - SL20Constants.SL20_COMMAND_CONTAINER_RESULT, SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT, - result, encryptedResult); - final String encodedCommand = command.toString(); - - //TODO: add real implementation - //create header and footer - final String dummyHeader = createJsonSignedHeader(signer).toString(); - final String dummyFooter = createJsonSignedFooter(signer); - - return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "." - + Base64.getUrlEncoder().encodeToString(encodedCommand.getBytes()) + "." - + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes()); - - } - - /** - * Create parameters for Redirect command - * - * @param url - * @param command - * @param signedCommand - * @param ipcRedirect - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createRedirectCommandParameters(String url, ObjectNode command, ObjectNode signedCommand, Boolean ipcRedirect) throws SLCommandoBuildException{ - final ObjectNode redirectReqParams = mapper.getMapper().createObjectNode(); - addOnlyOnceOfTwo(redirectReqParams, - SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, - command, signedCommand); - addSingleStringElement(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, url, false); - addSingleBooleanElement(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT, ipcRedirect, false); - return redirectReqParams; - - } - - /** - * Create parameters for Call command - * - * @param url - * @param method - * @param includeTransactionId - * @param reqParameters - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createCallCommandParameters(String url, String method, Boolean includeTransactionId, Map<String, String> reqParameters) throws SLCommandoBuildException { - final ObjectNode callReqParams = mapper.getMapper().createObjectNode(); - addSingleStringElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_URL, url, true); - addSingleStringElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD, method, true); - addSingleBooleanElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID, includeTransactionId, false); - addArrayOfStringElements(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER, reqParameters); - return callReqParams; - - } - - /** - * Create result for Error command - * - * @param errorCode - * @param errorMsg - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createErrorCommandResult(String errorCode, String errorMsg) throws SLCommandoBuildException { - final ObjectNode result = mapper.getMapper().createObjectNode(); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, errorCode, true); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, errorMsg, true); - return result; - - } - - /** - * Create parameters for qualifiedeID command - * - * @param consentTemplateId Identifier of the template that is used for consent visualization - * @param consent Consent that has to be signed by user - * @param dataUrl - * @param additionalReqParameters - * @param x5cEnc - * @return - * @throws CertificateEncodingException - * @throws SLCommandoBuildException - */ - public static ObjectNode createQualifiedeEIDConsent(String consentTemplateId, byte[] consent, String dataUrl, - X509Certificate x5cEnc) throws CertificateEncodingException, SLCommandoBuildException { - final ObjectNode params = mapper.getMapper().createObjectNode(); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_CONSENTTEMPLATEID, consentTemplateId, true); - addSingleByteElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_CONSENT, consent, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_DATAURL, dataUrl, true); - addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false); - return params; - - } - - - /** - * Create parameters for qualifiedeID command - * - * @param authBlockId - * @param dataUrl - * @param additionalReqParameters - * @param x5cEnc - * @return - * @throws CertificateEncodingException - * @throws SLCommandoBuildException - */ - @Deprecated - public static ObjectNode createQualifiedeIDCommandParameters(String authBlockId, String dataUrl, - Map<String, String> additionalReqParameters, X509Certificate x5cEnc) throws CertificateEncodingException, SLCommandoBuildException { - final ObjectNode params = mapper.getMapper().createObjectNode(); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_AUTHBLOCKID, authBlockId, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_DATAURL, dataUrl, true); - addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES, additionalReqParameters); - addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false); - return params; - - } - - /** - * Create result for qualifiedeID command - * - * @param idl - * @param authBlock - * @param ccsURL - * @param LoA - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createQualifiedeIDCommandResult(byte[] idl, byte[] authBlock, String ccsURL, String LoA) throws SLCommandoBuildException { - final ObjectNode result = mapper.getMapper().createObjectNode(); - addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL, idl, true); - addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, authBlock, true); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, ccsURL, true); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, LoA, true); - return result; - - } - - - /** - * Create Binding-Key command parameters - * - * @param kontoId - * @param subjectName - * @param keySize - * @param keyAlg - * @param policies - * @param dataUrl - * @param x5cVdaTrust - * @param reqUserPassword - * @param x5cEnc - * @return - * @throws SLCommandoBuildException - * @throws CertificateEncodingException - */ - public static ObjectNode createBindingKeyCommandParams(String kontoId, String subjectName, int keySize, String keyAlg, - Map<String, String> policies, String dataUrl, X509Certificate x5cVdaTrust, Boolean reqUserPassword, X509Certificate x5cEnc) throws SLCommandoBuildException, CertificateEncodingException { - final ObjectNode params = mapper.getMapper().createObjectNode(); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID, kontoId, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_SN, subjectName, true); - addSingleNumberElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH, keySize, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG, keyAlg, true); - addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES, policies); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL, dataUrl, true); - addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST, x5cVdaTrust, false); - addSingleBooleanElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD, reqUserPassword, false); - addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC, x5cEnc, false); - return params; - - } - - /** - * Create Binding-Key command result - * - * @param appId - * @param csr - * @param attCert - * @param password - * @return - * @throws SLCommandoBuildException - * @throws CertificateEncodingException - */ - public static ObjectNode createBindingKeyCommandResult(String appId, byte[] csr, X509Certificate attCert, byte[] password) throws SLCommandoBuildException, CertificateEncodingException { - final ObjectNode result = mapper.getMapper().createObjectNode(); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID, appId, true); - addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR, csr, true); - addSingleCertificateElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE, attCert, false); - addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD, password, false); - return result; - - } - - /** - * Create Store Binding-Certificate command parameters - * - * @param cert - * @param dataUrl - * @return - * @throws CertificateEncodingException - * @throws SLCommandoBuildException - */ - public static ObjectNode createStoreBindingCertCommandParams(X509Certificate cert, String dataUrl) throws CertificateEncodingException, SLCommandoBuildException { - final ObjectNode params = mapper.getMapper().createObjectNode(); - addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE, cert, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_DATAURL, dataUrl, true); - return params; - - } - - /** - * Create Store Binding-Certificate command result - * - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createStoreBindingCertCommandSuccessResult() throws SLCommandoBuildException { - final ObjectNode result = mapper.getMapper().createObjectNode(); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS, - SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE, true); - return result; - - } - - - /** - * Create idAndPassword command parameters - * - * @param keyAlg - * @param dataUrl - * @param x5cEnc - * @return - * @throws SLCommandoBuildException - * @throws CertificateEncodingException - */ - public static ObjectNode createIdAndPasswordCommandParameters(String keyAlg, String dataUrl, X509Certificate x5cEnc) throws SLCommandoBuildException, CertificateEncodingException { - final ObjectNode params = mapper.getMapper().createObjectNode(); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG, keyAlg, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL, dataUrl, true); - addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC, x5cEnc, false); - return params; - - } - - /** - * Create idAndPassword command result - * - * @param kontoId - * @param password - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createIdAndPasswordCommandResult(String kontoId, byte[] password) throws SLCommandoBuildException { - final ObjectNode result = mapper.getMapper().createObjectNode(); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID, kontoId, true); - addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD, password, true); - return result; - - } - - /** - * Create JWS Token Authentication command - * - * @param nonce - * @param dataUrl - * @param displayData - * @param displayUrl - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createJwsTokenAuthCommandParams(String nonce, String dataUrl, List<String> displayData, List<String> displayUrl) throws SLCommandoBuildException { - final ObjectNode params = mapper.getMapper().createObjectNode(); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE, nonce, true); - addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL, dataUrl, true); - addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA, displayData); - addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL, displayUrl); - return params; - - } - - /** - * Create JWS Token Authentication command result - * - * @param nonce - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createJwsTokenAuthCommandResult(String nonce) throws SLCommandoBuildException { - final ObjectNode result = mapper.getMapper().createObjectNode(); - addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE, nonce, true); - return result; - - } - - - /** - * Create Generic Request Container - * - * @param reqId - * @param transactionId - * @param payLoad - * @param signedPayload - * @return - * @throws SLCommandoBuildException - */ - public static ObjectNode createGenericRequest(String reqId, String transactionId, ObjectNode payLoad, String signedPayload) throws SLCommandoBuildException { - final ObjectNode req = mapper.getMapper().createObjectNode(); - addSingleIntegerElement(req, SL20Constants.SL20_VERSION, SL20Constants.CURRENT_SL20_VERSION, true); - addSingleStringElement(req, SL20Constants.SL20_REQID, reqId, true); - addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false); - addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, - payLoad, signedPayload); - return req; - - } - - /** - * Create Generic Response Container - * - * @param respId - * @param inResponseTo - * @param transactionId - * @param payLoad - * @param signedPayload - * @return - * @throws SLCommandoBuildException - */ - public static final ObjectNode createGenericResponse(String respId, String inResponseTo, String transactionId, - ObjectNode payLoad, String signedPayload) throws SLCommandoBuildException { - final ObjectNode req = mapper.getMapper().createObjectNode(); - addSingleIntegerElement(req, SL20Constants.SL20_VERSION, SL20Constants.CURRENT_SL20_VERSION, true); - addSingleStringElement(req, SL20Constants.SL20_RESPID, respId, true); - addSingleStringElement(req, SL20Constants.SL20_INRESPTO, inResponseTo, false); - addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false); - addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, - payLoad, signedPayload); - return req; - - } - - /** - * Add one element of two possible elements <br> - * This method adds either the first element or the second element to parent JSON, but never both. - * - * @param parent Parent JSON element - * @param firstKeyId first element Id - * @param secondKeyId second element Id - * @param first first element - * @param second second element - * @throws SLCommandoBuildException - */ - public static void addOnlyOnceOfTwo(ObjectNode parent, String firstKeyId, String secondKeyId, ObjectNode first, String second) throws SLCommandoBuildException { - if (first == null && (second == null || second.isEmpty())) - throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL"); - - else if (first != null && second != null) - throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE"); - - else if (first != null) - parent.set(firstKeyId, first); - - else if (second != null && !second.isEmpty()) - parent.put(secondKeyId, second); - - else - throw new SLCommandoBuildException("Internal build error"); - } - - - - //TODO!!!! - private static ObjectNode createJsonSignedHeader(JsonSecurityUtils signer) throws SLCommandoBuildException { - final ObjectNode header = mapper.getMapper().createObjectNode(); - addSingleStringElement(header, SL20Constants.JSON_ALGORITHM, SL20Constants.JSON_ALGORITHM_SIGNING_RS256, true); - addSingleStringElement(header, SL20Constants.JSON_CONTENTTYPE, SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND, true); - addArrayOfStrings(header, SL20Constants.JSON_X509_CERTIFICATE, Arrays.asList(Constants.DUMMY_SIGNING_CERT)); - - return header; - } - - //TODO!!!! - private static ObjectNode createJsonEncryptionHeader(JsonSecurityUtils signer) throws SLCommandoBuildException { - final ObjectNode header = mapper.getMapper().createObjectNode(); - addSingleStringElement(header, SL20Constants.JSON_ALGORITHM, SL20Constants.JSON_ALGORITHM_ENC_KEY_RSAOAEP, true); - addSingleStringElement(header, SL20Constants.JSON_ENCRYPTION_PAYLOAD, SL20Constants.JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256, true); - addSingleStringElement(header, SL20Constants.JSON_CONTENTTYPE, SL20Constants.SL20_CONTENTTYPE_ENCRYPTED_RESULT, true); - addSingleStringElement(header, SL20Constants.JSON_X509_FINGERPRINT, Constants.DUMMY_SIGNING_CERT_FINGERPRINT, true); - - return header; - } - - //TODO!!!! - private static String createJsonSignedFooter(JsonSecurityUtils signer) { - return "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7\n" + - " AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4\n" + - " BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K\n" + - " 0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv\n" + - " hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB\n" + - " p0igcN_IoypGlUPQGe77Rw"; - } - - - - private static void addArrayOfStrings(ObjectNode parent, String keyId, List<String> values) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - if (values != null) { - final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); - parent.set(keyId, callReqParamsArray ); - for(final String el : values) - callReqParamsArray.add(el); - - } - } - - - private static void addArrayOfStringElements(ObjectNode parent, String keyId, Map<String, String> keyValuePairs) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - if (keyValuePairs != null) { - final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); - parent.set(keyId, callReqParamsArray); - - for(final Entry<String, String> el : keyValuePairs.entrySet()) { - final ObjectNode callReqParams = mapper.getMapper().createObjectNode(); - callReqParams.put(el.getKey(), el.getValue()); - callReqParamsArray.add(callReqParams); - - } - } - } - - private static void addSingleCertificateElement(ObjectNode parent, String keyId, X509Certificate cert, boolean isRequired) throws CertificateEncodingException, SLCommandoBuildException { - if (cert != null) - addSingleByteElement(parent, keyId, cert.getEncoded(), isRequired); - - else if (isRequired) - throw new SLCommandoBuildException(keyId + " is marked as REQUIRED"); - - } - - - - private static void addSingleByteElement(ObjectNode parent, String keyId, byte[] value, boolean isRequired) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - - if (isRequired && value == null) - throw new SLCommandoBuildException(keyId + " has NULL value"); - - else if (value != null) - parent.put(keyId, Base64.getEncoder().encodeToString(value)); - - } - - private static void addSingleBooleanElement(ObjectNode parent, String keyId, Boolean value, boolean isRequired) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - - if (isRequired && value == null) - throw new SLCommandoBuildException(keyId + " has a NULL value"); - - else if (value != null) - parent.put(keyId, value); - - } - - private static void addSingleNumberElement(ObjectNode parent, String keyId, Integer value, boolean isRequired) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - - if (isRequired && value == null) - throw new SLCommandoBuildException(keyId + " has a NULL value"); - - else if (value != null) - parent.put(keyId, value);; - - } - - private static void addSingleStringElement(ObjectNode parent, String keyId, String value, boolean isRequired) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - - if (isRequired && (value == null || value.isEmpty())) - throw new SLCommandoBuildException(keyId + " has an empty value"); - - else if (value != null && !value.isEmpty()) - parent.put(keyId, value); - - } - - private static void addSingleIntegerElement(ObjectNode parent, String keyId, Integer value, boolean isRequired) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - - if (isRequired && value == null) - throw new SLCommandoBuildException(keyId + " has an empty value"); - - else if (value != null) - parent.put(keyId, value); - - } - - private static void addSingleJSONElement(ObjectNode parent, String keyId, ObjectNode element, boolean isRequired) throws SLCommandoBuildException { - validateParentAndKey(parent, keyId); - - if (isRequired && element == null) - throw new SLCommandoBuildException("No commando name included"); - - else if (element != null) - parent.set(keyId, element); - - } - - private static void addOnlyOnceOfTwo(ObjectNode parent, String firstKeyId, String secondKeyId, ObjectNode first, ObjectNode second) throws SLCommandoBuildException { - if (first == null && second == null) - throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL"); - - else if (first != null && second != null) - throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE"); - - else if (first != null) - parent.set(firstKeyId, first); - - else if (second != null) - parent.set(secondKeyId, second); - - else - throw new SLCommandoBuildException("Internal build error"); - } - - private static void validateParentAndKey(ObjectNode parent, String keyId) throws SLCommandoBuildException { - if (parent == null) - throw new SLCommandoBuildException("NO parent JSON element"); - - if (keyId == null || keyId.isEmpty()) - throw new SLCommandoBuildException("NO JSON element identifier"); - } -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java deleted file mode 100644 index 314dde17..00000000 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java +++ /dev/null @@ -1,368 +0,0 @@ -package at.gv.egiz.eaaf.modules.auth.sl20.utils; - -import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.util.EntityUtils; -import org.jose4j.base64url.Base64Url; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException; - -public class SL20JSONExtractorUtils { - private static final Logger log = LoggerFactory.getLogger(SL20JSONExtractorUtils.class); - private static JsonMapper mapper = new JsonMapper(); - - - /** - * Extract String value from JSON - * - * @param input - * @param keyID - * @param isRequired - * @return - * @throws SLCommandoParserException - */ - public static String getStringValue(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException { - try { - final JsonNode internal = getAndCheck(input, keyID, isRequired); - - if (internal != null) - return internal.asText(); - else - return null; - - } catch (final SLCommandoParserException e) { - throw e; - - } catch (final Exception e) { - throw new SLCommandoParserException("Can not extract String value with keyId: " + keyID, e); - - } - } - - /** - * Extract Boolean value from JSON - * - * @param input - * @param keyID - * @param isRequired - * @return - * @throws SLCommandoParserException - */ - public static boolean getBooleanValue(ObjectNode input, String keyID, boolean isRequired, boolean defaultValue) throws SLCommandoParserException { - try { - final JsonNode internal = getAndCheck(input, keyID, isRequired); - - if (internal != null) - return internal.asBoolean(); - else - return defaultValue; - - } catch (final SLCommandoParserException e) { - throw e; - - } catch (final Exception e) { - throw new SLCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e); - - } - } - - /** - * Extract JSONObject value from JSON - * - * @param input - * @param keyID - * @param isRequired - * @return - * @throws SLCommandoParserException - */ - public static JsonNode getJSONObjectValue(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException { - try { - final JsonNode internal = getAndCheck(input, keyID, isRequired); - - if (internal != null) - return internal; - else - return null; - - } catch (final SLCommandoParserException e) { - throw e; - - } catch (final Exception e) { - throw new SLCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e); - - } - } - - /** - * Extract a List of String elements from a JSON element - * - * @param input - * @return - * @throws SLCommandoParserException - */ - public static List<String> getListOfStringElements(JsonNode input) throws SLCommandoParserException { - final List<String> result = new ArrayList<String>(); - if (input != null) { - if (input.isArray()) { - final Iterator<JsonNode> arrayIterator = input.iterator(); - while(arrayIterator.hasNext()) { - final JsonNode next = arrayIterator.next(); - if (next.isTextual()) - result.add(next.asText()); - } - - } else if (input.isTextual()) { - result.add(input.asText()); - - } else { - log.warn("JSON Element IS NOT a JSON array or a JSON Primitive"); - throw new SLCommandoParserException("JSON Element IS NOT a JSON array or a JSON Primitive"); - - } - } - - return result; - } - - /** - * Extract Map of Key/Value pairs from a JSON Element - * - * @param input parent JSON object - * @param keyID KeyId of the child that should be parsed - * @param isRequired - * @return - * @throws SLCommandoParserException - */ - public static Map<String, String> getMapOfStringElements(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException { - final JsonNode internal = getAndCheck(input, keyID, isRequired); - return getMapOfStringElements(internal); - - } - - /** - * Extract Map of Key/Value pairs from a JSON Element - * - * @param input - * @return - * @throws SLCommandoParserException - */ - public static Map<String, String> getMapOfStringElements(JsonNode input) throws SLCommandoParserException { - final Map<String, String> result = new HashMap<String, String>(); - - if (input != null) { - if (input.isArray()) { - final Iterator<JsonNode> arrayIterator = input.iterator(); - while(arrayIterator.hasNext()) { - final JsonNode next = arrayIterator.next(); - final Iterator<Entry<String, JsonNode>> entry = next.fields(); - entitySetToMap(result, entry); - - } - - } else if (input.isObject()) { - final Iterator<Entry<String, JsonNode>> objectKeys = input.fields(); - entitySetToMap(result, objectKeys); - - } else - throw new SLCommandoParserException("JSON Element IS NOT a JSON array or a JSON object"); - - } - - return result; - } - - private static void entitySetToMap(Map<String, String> result, Iterator<Entry<String, JsonNode>> entry) { - while (entry.hasNext()) { - final Entry<String, JsonNode> el = entry.next(); - if (result.containsKey(el.getKey())) - log.info("Attr. Map already contains Element with Key: " + el.getKey() + ". Overwrite element ... "); - - result.put(el.getKey(), el.getValue().asText()); - - } - - } - - - public static JsonNode extractSL20Result(JsonNode command, IJOSETools decrypter, boolean mustBeEncrypted) throws SL20Exception { - final JsonNode result = command.get(SL20Constants.SL20_COMMAND_CONTAINER_RESULT); - final JsonNode encryptedResult = command.get(SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT); - - if (result == null && encryptedResult == null) - throw new SLCommandoParserException("NO result OR encryptedResult FOUND."); - - else if (encryptedResult == null && mustBeEncrypted) - throw new SLCommandoParserException("result MUST be encrypted."); - - else if (encryptedResult != null && encryptedResult.isTextual()) { - try { - return decrypter.decryptPayload(encryptedResult.asText()); - - } catch (final Exception e) { - log.info("Can NOT decrypt SL20 result. Reason:" + e.getMessage()); - if (!mustBeEncrypted) { - log.warn("Decrypted results are disabled by configuration. Parse result in plain if it is possible"); - - //dummy code - try { - final String[] signedPayload = encryptedResult.toString().split("\\."); - final JsonNode payLoad = mapper.getMapper().readTree(new String(Base64.getUrlDecoder().decode(signedPayload[1]))); - return payLoad; - - } catch (final Exception e1) { - log.debug("DummyCode FAILED, Reason: " + e1.getMessage() + " Ignore it ..."); - throw new SL20Exception(e.getMessage(), null, e); - - } - - } else - throw e; - - } - - } else if (result != null) { - return result; - - } else - throw new SLCommandoParserException("Internal build error"); - - - } - - /** - * Extract payLoad from generic transport container - * - * @param container - * @param joseTools - * @return - * @throws SLCommandoParserException - */ - public static VerificationResult extractSL20PayLoad(JsonNode container, IJOSETools joseTools, boolean mustBeSigned) throws SL20Exception { - - final JsonNode sl20Payload = container.get(SL20Constants.SL20_PAYLOAD); - final JsonNode sl20SignedPayload = container.get(SL20Constants.SL20_SIGNEDPAYLOAD); - - if (mustBeSigned && joseTools == null) - throw new SLCommandoParserException("'joseTools' MUST be set if 'mustBeSigned' is 'true'"); - - if (sl20Payload == null && sl20SignedPayload == null) - throw new SLCommandoParserException("NO payLoad OR signedPayload FOUND."); - - else if (sl20SignedPayload == null && mustBeSigned) - throw new SLCommandoParserException("payLoad MUST be signed."); - - else if (joseTools != null && sl20SignedPayload != null && sl20SignedPayload.isTextual()) { - return joseTools.validateSignature(sl20SignedPayload.asText()); - - } else if (sl20Payload != null) - return new VerificationResult(sl20Payload); - - else - throw new SLCommandoParserException("Internal build error"); - - - } - - - /** - * Extract generic transport container from httpResponse - * - * @param httpResp - * @return - * @throws SLCommandoParserException - */ - public static JsonNode getSL20ContainerFromResponse(HttpResponse httpResp) throws SLCommandoParserException { - try { - JsonNode sl20Resp = null; - if (httpResp.getStatusLine().getStatusCode() == 303 || httpResp.getStatusLine().getStatusCode() == 307) { - final Header[] locationHeader = httpResp.getHeaders("Location"); - if (locationHeader == null) - throw new SLCommandoParserException("Find Redirect statuscode but not Location header"); - - final String sl20RespString = new URIBuilder(locationHeader[0].getValue()).getQueryParams().get(0).getValue(); - sl20Resp = mapper.getMapper().readTree(Base64Url.decode(sl20RespString)); - - } else if (httpResp.getStatusLine().getStatusCode() == 200) { - if (httpResp.getEntity().getContentType() == null) - throw new SLCommandoParserException("SL20 response contains NO ContentType"); - - if (!httpResp.getEntity().getContentType().getValue().startsWith("application/json")) - throw new SLCommandoParserException("SL20 response with a wrong ContentType: " + httpResp.getEntity().getContentType().getValue()); - sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity()); - - } else if ( (httpResp.getStatusLine().getStatusCode() == 500) || - (httpResp.getStatusLine().getStatusCode() == 401) || - (httpResp.getStatusLine().getStatusCode() == 400) ) { - log.info("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode() - + ". Search for error message"); - - try { - sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity()); - - } catch (final Exception e) { - log.warn("SL20 response contains no valid JSON", e); - throw new SLCommandoParserException("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode() - + " AND NO valid JSON errormsg", e); - - } - - - - } else - throw new SLCommandoParserException("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode()); - - log.info("Find JSON object in http response"); - return sl20Resp; - - } catch (final Exception e) { - throw new SLCommandoParserException("SL20 response parsing FAILED! Reason: " + e.getMessage(), e); - - } - } - - private static JsonNode parseSL20ResultFromResponse(HttpEntity resp) throws Exception { - if (resp != null && resp.getContent() != null) { - final String rawSL20Resp = EntityUtils.toString(resp); - final JsonNode sl20Resp = mapper.getMapper().readTree(rawSL20Resp); - - //TODO: check sl20Resp type like && sl20Resp.isJsonObject() - if (sl20Resp != null) { - return sl20Resp; - - } else - throw new SLCommandoParserException("SL2.0 can NOT parse to a JSON object"); - - - } else - throw new SLCommandoParserException("Can NOT find content in http response"); - - } - - - private static JsonNode getAndCheck(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException { - final JsonNode internal = input.get(keyID); - - if (internal == null && isRequired) - throw new SLCommandoParserException("REQUIRED Element with keyId: " + keyID + " does not exist"); - - return internal; - - } -} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonBuilderUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonBuilderUtils.java new file mode 100644 index 00000000..f505f28d --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonBuilderUtils.java @@ -0,0 +1,731 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.utils; + +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import at.gv.egiz.eaaf.modules.auth.sl20.Constants; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class SL20JsonBuilderUtils { + + private static JsonMapper mapper = new JsonMapper(); + + /** + * Create command request. + * + * @param name Commando name + * @param params Commando parameters + * @return JSON Object + * @throws SlCommandoBuildException In case of a build error + */ + public static ObjectNode createCommand(final String name, final ObjectNode params) + throws SlCommandoBuildException { + + final ObjectNode command = mapper.getMapper().createObjectNode(); + addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); + addSingleJsonElement(command, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, params, true); + return command; + + } + + /** + * Create signed command request. + * + * @param name Commando name + * @param params commando parameter + * @param signer JWS signer implementation + * @return Serialized JWS + * @throws SlCommandoBuildException In case of a build error + */ + public static String createSignedCommand(final String name, final ObjectNode params, + final IJoseTools signer) throws SlCommandoBuildException { + final ObjectNode command = mapper.getMapper().createObjectNode(); + addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); + addSingleJsonElement(command, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, params, true); + return signer.createSignature(command.toString()); + + } + + + /** + * Create encrypted command result. + * + * @param result JSON to encrypt + * @param encrypter JWE encrypter implementation + * @return Serialized JWE + * @throws SlCommandoBuildException In case of a processing error + */ + public static String createEncryptedCommandoResult(final ObjectNode result, + final JsonSecurityUtils encrypter) throws SlCommandoBuildException { + // TODO: add real implementation + // create header and footer + final String dummyHeader = createJsonEncryptionHeader(encrypter).toString(); + final String payLoad = result.toString(); + final String dummyFooter = createJsonSignedFooter(encrypter); + + return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "." + + Base64.getUrlEncoder().encodeToString(payLoad.getBytes()) + "." + + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes()); + + } + + + /** + * Create command result. + * + * @param name Commando name + * @param result commande result + * @param encryptedResult encrypted commando result + * @return Result json + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createCommandResponse(final String name, final ObjectNode result, + final String encryptedResult) throws SlCommandoBuildException { + final ObjectNode command = mapper.getMapper().createObjectNode(); + addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); + addOnlyOnceOfTwo(command, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, + SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT, result, encryptedResult); + return command; + + } + + /** + * Create signed command result. + * + * @param name commando name + * @param result commando result + * @param encryptedResult encrypted commando result + * @return JWS in serialized form + * @throws SlCommandoBuildException in case of an error + + */ + public static String createSignedCommandResponse(final String name, final ObjectNode result, + final String encryptedResult, final JsonSecurityUtils signer) + throws SlCommandoBuildException { + final ObjectNode command = mapper.getMapper().createObjectNode(); + addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); + addOnlyOnceOfTwo(command, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, + SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT, result, encryptedResult); + final String encodedCommand = command.toString(); + + // TODO: add real implementation + // create header and footer + final String dummyHeader = createJsonSignedHeader(signer).toString(); + final String dummyFooter = createJsonSignedFooter(signer); + + return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "." + + Base64.getUrlEncoder().encodeToString(encodedCommand.getBytes()) + "." + + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes()); + + } + + /** + * Create parameters for Redirect command. + * + * @param url redirect URL + * @param command embedded command + * @param signedCommand Signed embedded command + * @param ipcRedirect IPC redirect flag + * @return result JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createRedirectCommandParameters(final String url, + final ObjectNode command, final ObjectNode signedCommand, final Boolean ipcRedirect) + throws SlCommandoBuildException { + final ObjectNode redirectReqParams = mapper.getMapper().createObjectNode(); + addOnlyOnceOfTwo(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, command, signedCommand); + addSingleStringElement(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, + url, false); + addSingleBooleanElement(redirectReqParams, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT, ipcRedirect, false); + return redirectReqParams; + + } + + /** + * Create parameters for Call command. + * + * @param url http URL for Call command + * @param method http method used by call commando result + * @param includeTransactionId TransactionId + * @param reqParameters Request parameters on CALL command + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createCallCommandParameters(final String url, final String method, + final Boolean includeTransactionId, final Map<String, String> reqParameters) + throws SlCommandoBuildException { + final ObjectNode callReqParams = mapper.getMapper().createObjectNode(); + addSingleStringElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_URL, url, + true); + addSingleStringElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD, + method, true); + addSingleBooleanElement(callReqParams, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID, includeTransactionId, + false); + addArrayOfStringElements(callReqParams, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER, reqParameters); + return callReqParams; + + } + + /** + * Create result for Error command. + * + * @param errorCode Error-Code + * @param errorMsg Error-message + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createErrorCommandResult(final String errorCode, final String errorMsg) + throws SlCommandoBuildException { + final ObjectNode result = mapper.getMapper().createObjectNode(); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, + errorCode, true); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, + errorMsg, true); + return result; + + } + + /** + * Create parameters for qualifiedeID command. + * + * @param consentTemplateId Identifier of the template that is used for consent visualization + * @param consent Consent that has to be signed by user + * @param dataUrl DataURL for result + * @param x5cEnc Response encryption certificate + * @return JSON + * @throws CertificateEncodingException In case of a encryption certificate encoding problem + * @throws SlCommandoBuildException In case of a generel error + */ + public static ObjectNode createQualifiedeEidConsent(final String consentTemplateId, + final byte[] consent, final String dataUrl, final X509Certificate x5cEnc) + throws CertificateEncodingException, SlCommandoBuildException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_CONSENTTEMPLATEID, + consentTemplateId, true); + addSingleByteElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_CONSENT, consent, true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_DATAURL, dataUrl, true); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false); + return params; + + } + + + /** + * Create parameters for qualifiedeID command. + * + * @param authBlockId AuthBlock transformation Id + * @param dataUrl DataURL for result + * @param additionalReqParameters additional parameters + * @param x5cEnc Response encryption certificate + * @return JSON + * @throws CertificateEncodingException In case of a encryption certificate encoding problem + * @throws SlCommandoBuildException In case of a generel error + */ + @Deprecated + public static ObjectNode createQualifiedEidCommandParameters(final String authBlockId, + final String dataUrl, final Map<String, String> additionalReqParameters, + final X509Certificate x5cEnc) throws CertificateEncodingException, SlCommandoBuildException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_AUTHBLOCKID, authBlockId, + true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_DATAURL, dataUrl, true); + addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES, + additionalReqParameters); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false); + return params; + + } + + /** + * Create result for qualifiedeID command. + * + * @param idl IdentityLink + * @param authBlock AuthBlock + * @param ccsUrl VDA URL + * @param loa LoA + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createQualifiedEidCommandResult(final byte[] idl, final byte[] authBlock, + final String ccsUrl, final String loa) throws SlCommandoBuildException { + final ObjectNode result = mapper.getMapper().createObjectNode(); + addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL, idl, true); + addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, authBlock, + true); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, ccsUrl, + true); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, loa, true); + return result; + + } + + + /** + * Create Binding-Key command parameters. + * + * @param kontoId KontoId + * @param subjectName SubjectName + * @param keySize KeySize + * @param keyAlg Key-algorithm + * @param policies Key policy + * @param dataUrl DataURL + * @param x5cVdaTrust trusted certificate from VDA + * @param reqUserPassword User passwort initialize request + * @param x5cEnc Result encryption certificate + * @return JSON + * @throws SlCommandoBuildException in case of an errr + * @throws CertificateEncodingException In case of a certificate error + */ + public static ObjectNode createBindingKeyCommandParams(final String kontoId, + final String subjectName, final int keySize, final String keyAlg, + final Map<String, String> policies, final String dataUrl, final X509Certificate x5cVdaTrust, + final Boolean reqUserPassword, final X509Certificate x5cEnc) + throws SlCommandoBuildException, CertificateEncodingException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID, kontoId, + true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_SN, subjectName, + true); + addSingleNumberElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH, + keySize, true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG, keyAlg, + true); + addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES, + policies); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL, dataUrl, + true); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST, + x5cVdaTrust, false); + addSingleBooleanElement(params, + SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD, reqUserPassword, + false); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC, + x5cEnc, false); + return params; + + } + + /** + * Create Binding-Key command result. + * + * @param appId AppId + * @param csr CSR + * @param attCert Key-Attestation certificate + * @param password user's password + * @return JSON + * @throws SlCommandoBuildException In case of an error + * @throws CertificateEncodingException In case of a certificate processing error + */ + public static ObjectNode createBindingKeyCommandResult(final String appId, final byte[] csr, + final X509Certificate attCert, final byte[] password) + throws SlCommandoBuildException, CertificateEncodingException { + final ObjectNode result = mapper.getMapper().createObjectNode(); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID, + appId, true); + addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR, csr, + true); + addSingleCertificateElement(result, + SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE, attCert, + false); + addSingleByteElement(result, + SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD, password, false); + return result; + + } + + /** + * Create Store Binding-Certificate command parameters. + * + * @param cert Certificate + * @param dataUrl DATA URL + * @return JSON + * @throws CertificateEncodingException In case of a certificate processing error + * @throws SlCommandoBuildException In case of a error + */ + public static ObjectNode createStoreBindingCertCommandParams(final X509Certificate cert, + final String dataUrl) throws CertificateEncodingException, SlCommandoBuildException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE, + cert, true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_DATAURL, dataUrl, + true); + return params; + + } + + /** + * Create Store Binding-Certificate command result. + * + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createStoreBindingCertCommandSuccessResult() + throws SlCommandoBuildException { + final ObjectNode result = mapper.getMapper().createObjectNode(); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS, + SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE, true); + return result; + + } + + + /** + * Create idAndPassword command parameters. + * + * @param keyAlg key algorithm + * @param dataUrl DATA Url + * @param x5cEnc result encryption certificate + * @return JSON + * @throws SlCommandoBuildException In case of an error + * @throws CertificateEncodingException In case of a certificate processing error + */ + public static ObjectNode createIdAndPasswordCommandParameters(final String keyAlg, + final String dataUrl, final X509Certificate x5cEnc) + throws SlCommandoBuildException, CertificateEncodingException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG, + keyAlg, true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL, + dataUrl, true); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC, + x5cEnc, false); + return params; + + } + + /** + * Create idAndPassword command result. + * + * @param kontoId User's Id + * @param password User's password + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createIdAndPasswordCommandResult(final String kontoId, + final byte[] password) throws SlCommandoBuildException { + final ObjectNode result = mapper.getMapper().createObjectNode(); + addSingleStringElement(result, + SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID, kontoId, true); + addSingleByteElement(result, + SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD, password, true); + return result; + + } + + /** + * Create JWS Token Authentication command. + * + * @param nonce nonce that should be signed + * @param dataUrl Data URL + * @param displayData Data that should be displayed + * @param displayUrl URL to data that should be displayed + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createJwsTokenAuthCommandParams(final String nonce, final String dataUrl, + final List<String> displayData, final List<String> displayUrl) + throws SlCommandoBuildException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE, nonce, + true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL, dataUrl, + true); + addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA, + displayData); + addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL, + displayUrl); + return params; + + } + + /** + * Create JWS Token Authentication command result. + * + * @param nonce Serialzed JWS that contains the signed nonce + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createJwsTokenAuthCommandResult(final String nonce) + throws SlCommandoBuildException { + final ObjectNode result = mapper.getMapper().createObjectNode(); + addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE, + nonce, true); + return result; + + } + + + /** + * Create Generic Request Container. + * + * @param reqId RequestId + * @param transactionId TransactionId + * @param payLoad unsigned payload + * @param signedPayload Signed payload + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static ObjectNode createGenericRequest(final String reqId, final String transactionId, + final ObjectNode payLoad, final String signedPayload) throws SlCommandoBuildException { + final ObjectNode req = mapper.getMapper().createObjectNode(); + addSingleIntegerElement(req, SL20Constants.SL20_VERSION, SL20Constants.CURRENT_SL20_VERSION, + true); + addSingleStringElement(req, SL20Constants.SL20_REQID, reqId, true); + addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false); + addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, payLoad, + signedPayload); + return req; + + } + + /** + * Create Generic Response Container. + * + * @param respId Response Id + * @param inResponseTo RequestId to this response + * @param transactionId transactionId + * @param payLoad Unsigned payload + * @param signedPayload Signed payload + * @return JSON + * @throws SlCommandoBuildException In case of an error + */ + public static final ObjectNode createGenericResponse(final String respId, + final String inResponseTo, final String transactionId, final ObjectNode payLoad, + final String signedPayload) throws SlCommandoBuildException { + final ObjectNode req = mapper.getMapper().createObjectNode(); + addSingleIntegerElement(req, SL20Constants.SL20_VERSION, SL20Constants.CURRENT_SL20_VERSION, + true); + addSingleStringElement(req, SL20Constants.SL20_RESPID, respId, true); + addSingleStringElement(req, SL20Constants.SL20_INRESPTO, inResponseTo, false); + addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false); + addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, payLoad, + signedPayload); + return req; + + } + + private static void addOnlyOnceOfTwo(final ObjectNode parent, final String firstKeyId, + final String secondKeyId, final ObjectNode first, final ObjectNode second) + throws SlCommandoBuildException { + if (first == null && second == null) { + throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL"); + } else if (first != null && second != null) { + throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE"); + } else if (first != null) { + parent.set(firstKeyId, first); + } else if (second != null) { + parent.set(secondKeyId, second); + } else { + throw new SlCommandoBuildException("Internal build error"); + } + } + + /** + * Add one element of two possible elements <br> + * This method adds either the first element or the second element to parent JSON, but never both. + * + * @param parent Parent JSON element + * @param firstKeyId first element Id + * @param secondKeyId second element Id + * @param first first element + * @param second second element + * @throws SlCommandoBuildException In case of an error. + */ + public static void addOnlyOnceOfTwo(final ObjectNode parent, final String firstKeyId, + final String secondKeyId, final ObjectNode first, final String second) + throws SlCommandoBuildException { + if (first == null && (second == null || second.isEmpty())) { + throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL"); + } else if (first != null && second != null) { + throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE"); + } else if (first != null) { + parent.set(firstKeyId, first); + } else if (second != null && !second.isEmpty()) { + parent.put(secondKeyId, second); + } else { + throw new SlCommandoBuildException("Internal build error"); + } + } + + + + // TODO!!!! + private static ObjectNode createJsonSignedHeader(final JsonSecurityUtils signer) + throws SlCommandoBuildException { + final ObjectNode header = mapper.getMapper().createObjectNode(); + addSingleStringElement(header, SL20Constants.JSON_ALGORITHM, + SL20Constants.JSON_ALGORITHM_SIGNING_RS256, true); + addSingleStringElement(header, SL20Constants.JSON_CONTENTTYPE, + SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND, true); + addArrayOfStrings(header, SL20Constants.JSON_X509_CERTIFICATE, + Arrays.asList(Constants.DUMMY_SIGNING_CERT)); + + return header; + } + + // TODO!!!! + private static ObjectNode createJsonEncryptionHeader(final JsonSecurityUtils signer) + throws SlCommandoBuildException { + final ObjectNode header = mapper.getMapper().createObjectNode(); + addSingleStringElement(header, SL20Constants.JSON_ALGORITHM, + SL20Constants.JSON_ALGORITHM_ENC_KEY_RSAOAEP, true); + addSingleStringElement(header, SL20Constants.JSON_ENCRYPTION_PAYLOAD, + SL20Constants.JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256, true); + addSingleStringElement(header, SL20Constants.JSON_CONTENTTYPE, + SL20Constants.SL20_CONTENTTYPE_ENCRYPTED_RESULT, true); + addSingleStringElement(header, SL20Constants.JSON_X509_FINGERPRINT, + Constants.DUMMY_SIGNING_CERT_FINGERPRINT, true); + + return header; + } + + // TODO!!!! + private static String createJsonSignedFooter(final JsonSecurityUtils signer) { + return "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7\n" + + " AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4\n" + + " BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K\n" + + " 0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv\n" + + " hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB\n" + + " p0igcN_IoypGlUPQGe77Rw"; + } + + + + private static void addArrayOfStrings(final ObjectNode parent, final String keyId, + final List<String> values) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + if (values != null) { + final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); + parent.set(keyId, callReqParamsArray); + for (final String el : values) { + callReqParamsArray.add(el); + } + + } + } + + + private static void addArrayOfStringElements(final ObjectNode parent, final String keyId, + final Map<String, String> keyValuePairs) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + if (keyValuePairs != null) { + final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); + parent.set(keyId, callReqParamsArray); + + for (final Entry<String, String> el : keyValuePairs.entrySet()) { + final ObjectNode callReqParams = mapper.getMapper().createObjectNode(); + callReqParams.put(el.getKey(), el.getValue()); + callReqParamsArray.add(callReqParams); + + } + } + } + + private static void addSingleCertificateElement(final ObjectNode parent, final String keyId, + final X509Certificate cert, final boolean isRequired) + throws CertificateEncodingException, SlCommandoBuildException { + if (cert != null) { + addSingleByteElement(parent, keyId, cert.getEncoded(), isRequired); + } else if (isRequired) { + throw new SlCommandoBuildException(keyId + " is marked as REQUIRED"); + } + + } + + + + private static void addSingleByteElement(final ObjectNode parent, final String keyId, + final byte[] value, final boolean isRequired) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + + if (isRequired && value == null) { + throw new SlCommandoBuildException(keyId + " has NULL value"); + } else if (value != null) { + parent.put(keyId, Base64.getEncoder().encodeToString(value)); + } + + } + + private static void addSingleBooleanElement(final ObjectNode parent, final String keyId, + final Boolean value, final boolean isRequired) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + + if (isRequired && value == null) { + throw new SlCommandoBuildException(keyId + " has a NULL value"); + } else if (value != null) { + parent.put(keyId, value); + } + + } + + private static void addSingleNumberElement(final ObjectNode parent, final String keyId, + final Integer value, final boolean isRequired) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + + if (isRequired && value == null) { + throw new SlCommandoBuildException(keyId + " has a NULL value"); + } else if (value != null) { + parent.put(keyId, value); + } + + } + + private static void addSingleStringElement(final ObjectNode parent, final String keyId, + final String value, final boolean isRequired) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + + if (isRequired && (value == null || value.isEmpty())) { + throw new SlCommandoBuildException(keyId + " has an empty value"); + } else if (value != null && !value.isEmpty()) { + parent.put(keyId, value); + } + + } + + private static void addSingleIntegerElement(final ObjectNode parent, final String keyId, + final Integer value, final boolean isRequired) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + + if (isRequired && value == null) { + throw new SlCommandoBuildException(keyId + " has an empty value"); + } else if (value != null) { + parent.put(keyId, value); + } + + } + + private static void addSingleJsonElement(final ObjectNode parent, final String keyId, + final ObjectNode element, final boolean isRequired) throws SlCommandoBuildException { + validateParentAndKey(parent, keyId); + + if (isRequired && element == null) { + throw new SlCommandoBuildException("No commando name included"); + } else if (element != null) { + parent.set(keyId, element); + } + + } + + + + private static void validateParentAndKey(final ObjectNode parent, final String keyId) + throws SlCommandoBuildException { + if (parent == null) { + throw new SlCommandoBuildException("NO parent JSON element"); + } + + if (keyId == null || keyId.isEmpty()) { + throw new SlCommandoBuildException("NO JSON element identifier"); + } + } +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java new file mode 100644 index 00000000..f4b5a724 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java @@ -0,0 +1,407 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.utils; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.util.EntityUtils; +import org.jose4j.base64url.Base64Url; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class SL20JsonExtractorUtils { + private static final Logger log = LoggerFactory.getLogger(SL20JsonExtractorUtils.class); + private static JsonMapper mapper = new JsonMapper(); + + + /** + * Extract String value from JSON. + * + * @param input JSON + * @param keyID Element identifier + * @param isRequired true, if the element must not null + * @return Value of this element + * @throws SlCommandoParserException In case an error + */ + public static String getStringValue(final JsonNode input, final String keyID, + final boolean isRequired) throws SlCommandoParserException { + try { + final JsonNode internal = getAndCheck(input, keyID, isRequired); + + if (internal != null) { + return internal.asText(); + } else { + return null; + } + + } catch (final SlCommandoParserException e) { + throw e; + + } catch (final Exception e) { + throw new SlCommandoParserException("Can not extract String value with keyId: " + keyID, e); + + } + } + + /** + * Extract Boolean value from JSON. + * + * @param input JSON + * @param keyID Element identifier + * @param isRequired true, if the element must not null + * @return Boolean + * @throws SlCommandoParserException In case of an error + */ + public static boolean getBooleanValue(final ObjectNode input, final String keyID, + final boolean isRequired, final boolean defaultValue) throws SlCommandoParserException { + try { + final JsonNode internal = getAndCheck(input, keyID, isRequired); + + if (internal != null) { + return internal.asBoolean(); + } else { + return defaultValue; + } + + } catch (final SlCommandoParserException e) { + throw e; + + } catch (final Exception e) { + throw new SlCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e); + + } + } + + /** + * Extract JSONObject value from JSON. + * + * @param input JSON + * @param keyID Element identifier + * @param isRequired true, if the element must not null + * @return JSON node + * @throws SlCommandoParserException In case of an error + */ + public static JsonNode getJsonObjectValue(final JsonNode input, final String keyID, + final boolean isRequired) throws SlCommandoParserException { + try { + final JsonNode internal = getAndCheck(input, keyID, isRequired); + + if (internal != null) { + return internal; + } else { + return null; + } + + } catch (final SlCommandoParserException e) { + throw e; + + } catch (final Exception e) { + throw new SlCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e); + + } + } + + /** + * Extract a List of String elements from a JSON element. + * + * @param input JSON + * @return List of Elements in this node + * @throws SlCommandoParserException In case of an error + */ + public static List<String> getListOfStringElements(final JsonNode input) + throws SlCommandoParserException { + final List<String> result = new ArrayList<>(); + if (input != null) { + if (input.isArray()) { + final Iterator<JsonNode> arrayIterator = input.iterator(); + while (arrayIterator.hasNext()) { + final JsonNode next = arrayIterator.next(); + if (next.isTextual()) { + result.add(next.asText()); + } + } + + } else if (input.isTextual()) { + result.add(input.asText()); + + } else { + log.warn("JSON Element IS NOT a JSON array or a JSON Primitive"); + throw new SlCommandoParserException("JSON Element IS NOT a JSON array or a JSON Primitive"); + + } + } + + return result; + } + + /** + * Extract Map of Key/Value pairs from a JSON Element. + * + * @param input parent JSON object + * @param keyID KeyId of the child that should be parsed + * @param isRequired true, if the element must not null + * @return Map of element pairs + * @throws SlCommandoParserException In case of an error + */ + public static Map<String, String> getMapOfStringElements(final JsonNode input, final String keyID, + final boolean isRequired) throws SlCommandoParserException { + final JsonNode internal = getAndCheck(input, keyID, isRequired); + return getMapOfStringElements(internal); + + } + + /** + * Extract Map of Key/Value pairs from a JSON Element. + * + * @param input JSON + * @return Map of element pairs + * @throws SlCommandoParserException in case of an error + */ + public static Map<String, String> getMapOfStringElements(final JsonNode input) + throws SlCommandoParserException { + final Map<String, String> result = new HashMap<>(); + + if (input != null) { + if (input.isArray()) { + final Iterator<JsonNode> arrayIterator = input.iterator(); + while (arrayIterator.hasNext()) { + final JsonNode next = arrayIterator.next(); + final Iterator<Entry<String, JsonNode>> entry = next.fields(); + entitySetToMap(result, entry); + + } + + } else if (input.isObject()) { + final Iterator<Entry<String, JsonNode>> objectKeys = input.fields(); + entitySetToMap(result, objectKeys); + + } else { + throw new SlCommandoParserException("JSON Element IS NOT a JSON array or a JSON object"); + } + + } + + return result; + } + + private static void entitySetToMap(final Map<String, String> result, + final Iterator<Entry<String, JsonNode>> entry) { + while (entry.hasNext()) { + final Entry<String, JsonNode> el = entry.next(); + if (result.containsKey(el.getKey())) { + log.info("Attr. Map already contains Element with Key: " + el.getKey() + + ". Overwrite element ... "); + } + + result.put(el.getKey(), el.getValue().asText()); + + } + + } + + + /** + * Extract Security-Layer 2.0 result from response object. + * + * @param command SL2.0 command + * @param decrypter JWS decrypter implementation + * @param mustBeEncrypted if <code>true</code>, the result must be encrypted + * @return decrypted JSON + * @throws SL20Exception In case of an error + */ + public static JsonNode extractSL20Result(final JsonNode command, final IJoseTools decrypter, + final boolean mustBeEncrypted) throws SL20Exception { + final JsonNode result = command.get(SL20Constants.SL20_COMMAND_CONTAINER_RESULT); + final JsonNode encryptedResult = + command.get(SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT); + + if (result == null && encryptedResult == null) { + throw new SlCommandoParserException("NO result OR encryptedResult FOUND."); + } else if (encryptedResult == null && mustBeEncrypted) { + throw new SlCommandoParserException("result MUST be encrypted."); + } else if (encryptedResult != null && encryptedResult.isTextual()) { + try { + return decrypter.decryptPayload(encryptedResult.asText()); + + } catch (final Exception e) { + log.info("Can NOT decrypt SL20 result. Reason:" + e.getMessage()); + if (!mustBeEncrypted) { + log.warn( + "Decrypted results are disabled by configuration. Parse result in plain if it is possible"); + + // dummy code + try { + final String[] signedPayload = encryptedResult.toString().split("\\."); + final JsonNode payLoad = mapper.getMapper() + .readTree(new String(Base64.getUrlDecoder().decode(signedPayload[1]))); + return payLoad; + + } catch (final Exception e1) { + log.debug("DummyCode FAILED, Reason: " + e1.getMessage() + " Ignore it ..."); + throw new SL20Exception(e.getMessage(), null, e); + + } + + } else { + throw e; + } + + } + + } else if (result != null) { + return result; + + } else { + throw new SlCommandoParserException("Internal build error"); + } + + + } + + /** + * Extract payLoad from generic transport container. + * + * @param container JSON + * @param joseTools JWS implementation + * @return Signature verification result that contains the payLoad + * @throws SlCommandoParserException In case of an error + */ + public static VerificationResult extractSL20PayLoad(final JsonNode container, + final IJoseTools joseTools, final boolean mustBeSigned) throws SL20Exception { + + final JsonNode sl20Payload = container.get(SL20Constants.SL20_PAYLOAD); + final JsonNode sl20SignedPayload = container.get(SL20Constants.SL20_SIGNEDPAYLOAD); + + if (mustBeSigned && joseTools == null) { + throw new SlCommandoParserException("'joseTools' MUST be set if 'mustBeSigned' is 'true'"); + } + + if (sl20Payload == null && sl20SignedPayload == null) { + throw new SlCommandoParserException("NO payLoad OR signedPayload FOUND."); + } else if (sl20SignedPayload == null && mustBeSigned) { + throw new SlCommandoParserException("payLoad MUST be signed."); + } else if (joseTools != null && sl20SignedPayload != null && sl20SignedPayload.isTextual()) { + return joseTools.validateSignature(sl20SignedPayload.asText()); + + } else if (sl20Payload != null) { + return new VerificationResult(sl20Payload); + } else { + throw new SlCommandoParserException("Internal build error"); + } + + + } + + + /** + * Extract generic transport container from httpResponse. + * + * @param httpResp Http response object + * @return JSON with SL2.0 response + * @throws SlCommandoParserException In case of an error + */ + public static JsonNode getSL20ContainerFromResponse(final HttpResponse httpResp) + throws SlCommandoParserException { + try { + JsonNode sl20Resp = null; + if (httpResp.getStatusLine().getStatusCode() == 303 + || httpResp.getStatusLine().getStatusCode() == 307) { + final Header[] locationHeader = httpResp.getHeaders("Location"); + if (locationHeader == null) { + throw new SlCommandoParserException("Find Redirect statuscode but not Location header"); + } + + final String sl20RespString = + new URIBuilder(locationHeader[0].getValue()).getQueryParams().get(0).getValue(); + sl20Resp = mapper.getMapper().readTree(Base64Url.decode(sl20RespString)); + + } else if (httpResp.getStatusLine().getStatusCode() == 200) { + if (httpResp.getEntity().getContentType() == null) { + throw new SlCommandoParserException("SL20 response contains NO ContentType"); + } + + if (!httpResp.getEntity().getContentType().getValue().startsWith("application/json")) { + throw new SlCommandoParserException("SL20 response with a wrong ContentType: " + + httpResp.getEntity().getContentType().getValue()); + } + sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity()); + + } else if ((httpResp.getStatusLine().getStatusCode() == 500) + || (httpResp.getStatusLine().getStatusCode() == 401) + || (httpResp.getStatusLine().getStatusCode() == 400)) { + log.info("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode() + + ". Search for error message"); + + try { + sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity()); + + } catch (final Exception e) { + log.warn("SL20 response contains no valid JSON", e); + throw new SlCommandoParserException("SL20 response with http-code: " + + httpResp.getStatusLine().getStatusCode() + " AND NO valid JSON errormsg", e); + + } + + + + } else { + throw new SlCommandoParserException( + "SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode()); + } + + log.info("Find JSON object in http response"); + return sl20Resp; + + } catch (final Exception e) { + throw new SlCommandoParserException("SL20 response parsing FAILED! Reason: " + e.getMessage(), + e); + + } + } + + private static JsonNode parseSL20ResultFromResponse(final HttpEntity resp) throws Exception { + if (resp != null && resp.getContent() != null) { + final String rawSL20Resp = EntityUtils.toString(resp); + final JsonNode sl20Resp = mapper.getMapper().readTree(rawSL20Resp); + + // TODO: check sl20Resp type like && sl20Resp.isJsonObject() + if (sl20Resp != null) { + return sl20Resp; + + } else { + throw new SlCommandoParserException("SL2.0 can NOT parse to a JSON object"); + } + + + } else { + throw new SlCommandoParserException("Can NOT find content in http response"); + } + + } + + + private static JsonNode getAndCheck(final JsonNode input, final String keyID, + final boolean isRequired) throws SlCommandoParserException { + final JsonNode internal = input.get(keyID); + + if (internal == null && isRequired) { + throw new SlCommandoParserException( + "REQUIRED Element with keyId: " + keyID + " does not exist"); + } + + return internal; + + } +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/ISignatureVerificationService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/ISignatureVerificationService.java index a3243635..155bfadd 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/ISignatureVerificationService.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/ISignatureVerificationService.java @@ -1,84 +1,90 @@ package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api; import java.util.List; - import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.ICMSSignatureVerificationResponse; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IXMLSignatureVerificationResponse; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceException; public interface ISignatureVerificationService { - /** - * Verify a CAdES or CMS signature - * <br><br> - * <i>This method only validates the first CMS or CAdES signature if more than one signature exists</i> - * - * @param signature Enveloped CMS or CAdES signature - * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration - * @return @link {@link ICMSSignatureVerificationResponse}, or null if no signature was found - * @throws MOASigServiceException on signatue-verification error - */ - ICMSSignatureVerificationResponse verifyCMSSignature(byte[] signature, String trustProfileID) - throws MOASigServiceException; + /** + * Verify a CAdES or CMS signature. <br> + * <br> + * <i>This method only validates the first CMS or CAdES signature if more than one signature + * exists</i> + * + * @param signature Enveloped CMS or CAdES signature + * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration + * @return @link {@link ICMSSignatureVerificationResponse}, or null if no signature was found + * @throws MoaSigServiceException on signatue-verification error + */ + ICMSSignatureVerificationResponse verifyCmsSignature(byte[] signature, String trustProfileID) + throws MoaSigServiceException; - /** - * Verify a XML or XAdES signature - * <br><br> - * <i>This method only validates the first XML or XAdES signature if more than one signature exists</i> - * - * @param signature Serialized XML or XAdES signature - * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration - * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found - * @throws MOASigServiceException on signatue-verification error - */ - IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID) - throws MOASigServiceException; + /** + * Verify a XML or XAdES signature. <br> + * <br> + * <i>This method only validates the first XML or XAdES signature if more than one signature + * exists</i> + * + * @param signature Serialized XML or XAdES signature + * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration + * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found + * @throws MoaSigServiceException on signatue-verification error + */ + IXMLSignatureVerificationResponse verifyXmlSignature(byte[] signature, String trustProfileID) + throws MoaSigServiceException; - /** - * Verify a XML or XAdES signature - * <br><br> - * <i>This method only validates the first XML or XAdES signature if more than one signature exists</i> - * - * @param signature Serialized XML or XAdES signature - * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration - * @param verifyTransformsInfoProfileID {@link List} of XML Transformations that should be used for signature-verification - * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found - * @throws MOASigServiceException on signatue-verification error - */ - IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID, - List<String> verifyTransformsInfoProfileID) throws MOASigServiceException; + /** + * Verify a XML or XAdES signature. <br> + * <br> + * <i>This method only validates the first XML or XAdES signature if more than one signature + * exists</i> + * + * @param signature Serialized XML or XAdES signature + * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration + * @param verifyTransformsInfoProfileID {@link List} of XML Transformations that should be used + * for signature-verification + * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found + * @throws MoaSigServiceException on signatue-verification error + */ + IXMLSignatureVerificationResponse verifyXmlSignature(byte[] signature, String trustProfileID, + List<String> verifyTransformsInfoProfileID) throws MoaSigServiceException; - /** - * Verify a XML or XAdES signature - * <br><br> - * <i>This method only validates the first XML or XAdES signature if more than one signature exists</i> - * - * @param signature Serialized XML or XAdES signature - * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration - * @param signatureLocationXpath Xpath that points to location of Signature element - * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found - * @throws MOASigServiceException on signatue-verification error - */ - IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID, - String signatureLocationXpath) throws MOASigServiceException; + /** + * Verify a XML or XAdES signature. <br> + * <br> + * <i>This method only validates the first XML or XAdES signature if more than one signature + * exists</i> + * + * @param signature Serialized XML or XAdES signature + * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration + * @param signatureLocationXpath Xpath that points to location of Signature element + * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found + * @throws MoaSigServiceException on signatue-verification error + */ + IXMLSignatureVerificationResponse verifyXmlSignature(byte[] signature, String trustProfileID, + String signatureLocationXpath) throws MoaSigServiceException; - /** - * Verify a XML or XAdES signature - * <br><br> - * <i>This method only validates the first XML or XAdES signature if more than one signature exists</i> - * - * @param signature Serialized XML or XAdES signature - * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration - * @param verifyTransformsInfoProfileID {@link List} of XML Transformations that should be used for signature-verification - * @param signatureLocationXpath Xpath that points to location of Signature element - * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found - * @throws MOASigServiceException on signatue-verification error - */ - IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID, - List<String> verifyTransformsInfoProfileID, - String signatureLocationXpath) throws MOASigServiceException; + /** + * Verify a XML or XAdES signature. <br> + * <br> + * <i>This method only validates the first XML or XAdES signature if more than one signature + * exists</i> + * + * @param signature Serialized XML or XAdES signature + * @param trustProfileID Id of the Trust-Profile from MOA-Sig configuration + * @param verifyTransformsInfoProfileID {@link List} of XML Transformations that should be used + * for signature-verification + * @param signatureLocationXpath Xpath that points to location of Signature element + * @return @link {@link IXMLSignatureVerificationResponse}, or null if no signature was found + * @throws MoaSigServiceException on signatue-verification error + */ + IXMLSignatureVerificationResponse verifyXmlSignature(byte[] signature, String trustProfileID, + List<String> verifyTransformsInfoProfileID, String signatureLocationXpath) + throws MoaSigServiceException; -}
\ No newline at end of file +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IGenericSignatureVerificationResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IGenericSignatureVerificationResponse.java index 00d98c86..13a9b08f 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IGenericSignatureVerificationResponse.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IGenericSignatureVerificationResponse.java @@ -5,65 +5,71 @@ import java.util.Date; import org.springframework.lang.Nullable; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceException; public interface IGenericSignatureVerificationResponse { - /** - * Returns the signing time - * - * @return Signing time, or null if signature contains no time information - */ - @Nullable - Date getSigningDateTime(); - - /** - * Returns the signatureCheckCode. - * @return int - */ - int getSignatureCheckCode(); - - /** - * Returns the certificateCheckCode. - * @return int - */ - int getCertificateCheckCode(); + /** + * Returns the signing time + * + * @return Signing time, or null if signature contains no time information + */ + @Nullable + Date getSigningDateTime(); - /** - * Returns the qualifiedCertificate. - * @return boolean - */ - boolean isQualifiedCertificate(); + /** + * Returns the signatureCheckCode. + * + * @return int + */ + int getSignatureCheckCode(); - /** - * Returns the X509 certificate. - * @return X509Certificate, or null if no certificate information exists - * @throws MOASigServiceException if X509 certificate can not be deserialized - */ - @Nullable - X509Certificate getX509Certificate() throws MOASigServiceException; + /** + * Returns the certificateCheckCode. + * + * @return int + */ + int getCertificateCheckCode(); - - /** - * Returns the X509 certificate in serialized form - * - * @return Serialized X509 certificate, or null if no certificate information exists - */ - @Nullable - byte[] getX509CertificateEncoded(); - - /** - * Returns the publicAuthority. - * @return boolean - */ - boolean isPublicAuthority(); - - /** - * Returns the publicAuthorityCode. - * @return String OID, or null if no OID exists - */ - @Nullable - String getPublicAuthorityCode(); + /** + * Returns the qualifiedCertificate. + * + * @return boolean + */ + boolean isQualifiedCertificate(); + + /** + * Returns the X509 certificate. + * + * @return X509Certificate, or null if no certificate information exists + * @throws MoaSigServiceException if X509 certificate can not be deserialized + */ + @Nullable + X509Certificate getX509Certificate() throws MoaSigServiceException; + + + /** + * Returns the X509 certificate in serialized form + * + * @return Serialized X509 certificate, or null if no certificate information exists + */ + @Nullable + byte[] getX509CertificateEncoded(); + + /** + * Returns the publicAuthority. + * + * @return boolean + */ + boolean isPublicAuthority(); + + /** + * Returns the publicAuthorityCode. + * + * @return String OID, or null if no OID exists + */ + @Nullable + String getPublicAuthorityCode(); } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/ISchemaRessourceProvider.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/ISchemaRessourceProvider.java index 9548d96b..9bd5791f 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/ISchemaRessourceProvider.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/ISchemaRessourceProvider.java @@ -5,16 +5,17 @@ import java.util.Map; /** * Inject additional XML schemes into MOA-Sig - * + * * @author tlenz * */ public interface ISchemaRessourceProvider { - /** - * Get a Map of additional XML schemes that should be injected into MOA-Sig - * - * @return A Set of {@link Entry} consist of Name of the Scheme and XML scheme as {@link InputStream} - */ - public Map<String, InputStream> getSchemas(); + /** + * Get a Map of additional XML schemes that should be injected into MOA-Sig + * + * @return A Set of {@link Entry} consist of Name of the Scheme and XML scheme as + * {@link InputStream} + */ + public Map<String, InputStream> getSchemas(); } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IXMLSignatureVerificationResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IXMLSignatureVerificationResponse.java index 3e86fb63..6273bb9e 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IXMLSignatureVerificationResponse.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/api/data/IXMLSignatureVerificationResponse.java @@ -7,31 +7,34 @@ package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data; public interface IXMLSignatureVerificationResponse extends IGenericSignatureVerificationResponse { - /** - * Returns the xmlDSIGManifestCheckCode. - * @return int - */ - int getXmlDSIGManifestCheckCode(); - - /** - * Returns the xmlDsigSubjectName. - * @return String - */ - String getXmlDsigSubjectName(); - - - /** - * Returns the xmlDSIGManigest. - * @return boolean - */ - boolean isXmlDSIGManigest(); - - - /** - * Returns the the resulting code of the signature manifest check. - * - * @return The code of the sigature manifest check. - */ - int getSignatureManifestCheckCode(); - -}
\ No newline at end of file + /** + * Returns the xmlDSIGManifestCheckCode. + * + * @return int + */ + int getXmlDSIGManifestCheckCode(); + + /** + * Returns the xmlDsigSubjectName. + * + * @return String + */ + String getXmlDsigSubjectName(); + + + /** + * Returns the xmlDSIGManigest. + * + * @return boolean + */ + boolean isXmlDSIGManigest(); + + + /** + * Returns the the resulting code of the signature manifest check. + * + * @return The code of the sigature manifest check. + */ + int getSignatureManifestCheckCode(); + +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceBuilderException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceBuilderException.java deleted file mode 100644 index ded3f900..00000000 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceBuilderException.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; - -public class MOASigServiceBuilderException extends MOASigServiceException { - - private static final long serialVersionUID = 5178393157255309476L; - - public MOASigServiceBuilderException(String errorId, Object[] params) { - super(errorId, params); - } - - public MOASigServiceBuilderException(String errorId, Object[] params, Throwable e) { - super(errorId, params, e); - } -} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceConfigurationException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceConfigurationException.java deleted file mode 100644 index f3c02fe1..00000000 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceConfigurationException.java +++ /dev/null @@ -1,11 +0,0 @@ -package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; - -public class MOASigServiceConfigurationException extends MOASigServiceException { - - private static final long serialVersionUID = -4710795384615456488L; - - public MOASigServiceConfigurationException(String errorId, Object[] params, Throwable e) { - super(errorId, params, e); - } - -} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceException.java deleted file mode 100644 index 243b4b1d..00000000 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceException.java +++ /dev/null @@ -1,26 +0,0 @@ -package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; - -import at.gv.egiz.eaaf.core.exceptions.EAAFServiceException; - -public class MOASigServiceException extends EAAFServiceException { - - private static final long serialVersionUID = -6088238428550563658L; - private static final String MOA_SIG_SERVICE_ID = "MOA-SIG-VERIFY"; - - public MOASigServiceException(String errorId, Object[] params) { - super(errorId, params); - - } - - public MOASigServiceException(String errorId, Object[] params, Throwable e) { - super(errorId, params, e); - - } - - @Override - protected String getServiceIdentifier() { - return MOA_SIG_SERVICE_ID; - - } - -} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceParserException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceParserException.java deleted file mode 100644 index 63a51001..00000000 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MOASigServiceParserException.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; - -public class MOASigServiceParserException extends MOASigServiceException { - - private static final long serialVersionUID = 5178393157255309476L; - - public MOASigServiceParserException(String errorId, Object[] params) { - super(errorId, params); - } - - public MOASigServiceParserException(String errorId, Object[] params, Throwable e) { - super(errorId, params, e); - } -} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceBuilderException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceBuilderException.java new file mode 100644 index 00000000..e32ab932 --- /dev/null +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceBuilderException.java @@ -0,0 +1,14 @@ +package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; + +public class MoaSigServiceBuilderException extends MoaSigServiceException { + + private static final long serialVersionUID = 5178393157255309476L; + + public MoaSigServiceBuilderException(final String errorId, final Object[] params) { + super(errorId, params); + } + + public MoaSigServiceBuilderException(final String errorId, final Object[] params, final Throwable e) { + super(errorId, params, e); + } +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceConfigurationException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceConfigurationException.java new file mode 100644 index 00000000..fd5f8caf --- /dev/null +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceConfigurationException.java @@ -0,0 +1,11 @@ +package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; + +public class MoaSigServiceConfigurationException extends MoaSigServiceException { + + private static final long serialVersionUID = -4710795384615456488L; + + public MoaSigServiceConfigurationException(final String errorId, final Object[] params, final Throwable e) { + super(errorId, params, e); + } + +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceException.java new file mode 100644 index 00000000..a4fb6290 --- /dev/null +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceException.java @@ -0,0 +1,26 @@ +package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; + +import at.gv.egiz.eaaf.core.exceptions.EaafServiceException; + +public class MoaSigServiceException extends EaafServiceException { + + private static final long serialVersionUID = -6088238428550563658L; + private static final String MOA_SIG_SERVICE_ID = "MOA-SIG-VERIFY"; + + public MoaSigServiceException(final String errorId, final Object[] params) { + super(errorId, params); + + } + + public MoaSigServiceException(final String errorId, final Object[] params, final Throwable e) { + super(errorId, params, e); + + } + + @Override + protected String getServiceIdentifier() { + return MOA_SIG_SERVICE_ID; + + } + +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceParserException.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceParserException.java new file mode 100644 index 00000000..a47b45e0 --- /dev/null +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/exceptions/MoaSigServiceParserException.java @@ -0,0 +1,14 @@ +package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions; + +public class MoaSigServiceParserException extends MoaSigServiceException { + + private static final long serialVersionUID = 5178393157255309476L; + + public MoaSigServiceParserException(final String errorId, final Object[] params) { + super(errorId, params); + } + + public MoaSigServiceParserException(final String errorId, final Object[] params, final Throwable e) { + super(errorId, params, e); + } +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/AbstractSignatureService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/AbstractSignatureService.java index 7e65cec7..cbf80c39 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/AbstractSignatureService.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/AbstractSignatureService.java @@ -6,72 +6,71 @@ import javax.xml.parsers.ParserConfigurationException; import at.gv.egovernment.moa.spss.server.config.ConfigurationException; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator; -import at.gv.egovernment.moa.spss.server.logging.TransactionId; import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; import at.gv.egovernment.moaspss.logging.LoggingContext; import at.gv.egovernment.moaspss.logging.LoggingContextManager; -import iaik.server.Configurator; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.w3c.dom.Document; public abstract class AbstractSignatureService { - private static final Logger log = LoggerFactory.getLogger(AbstractSignatureService.class); + private static final Logger log = LoggerFactory.getLogger(AbstractSignatureService.class); + + @Autowired(required = true) + MoaSigInitializer moaSigConfig; + + /** + * Get a new {@link Document} from {@link DocumentBuilder} in synchronized form, because + * {@link DocumentBuilderFactory} and {@link DocumentBuilder} are not thread-safe. + * + * @return {@link Document} + * @throws ParserConfigurationException In case of an error + */ + protected synchronized Document getNewDocumentBuilder() throws ParserConfigurationException { + final DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + return docBuilder.newDocument(); - @Autowired(required = true) MoaSigInitializer moaSigConfig; - - /** - * Get a new {@link Document} from {@link DocumentBuilder} in synchronized form, because - * {@link DocumentBuilderFactory} and {@link DocumentBuilder} are not thread-safe. - * - * @return {@link Document} - * @throws ParserConfigurationException - */ - protected synchronized Document getNewDocumentBuilder() throws ParserConfigurationException { - final DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - return docBuilder.newDocument(); + } - } + /** + * Set up the thread-local context information needed for calling the various <code>Invoker</code> + * classes. + * + * @throws ConfigurationException An error occurred setting up the configuration in the + * <code>TransactionContext</code>. + */ + protected final void setUpContexts(final String transactionID) throws ConfigurationException { + final TransactionContextManager txMgr = TransactionContextManager.getInstance(); + final LoggingContextManager logMgr = LoggingContextManager.getInstance(); - /** - * Set up the thread-local context information needed for calling the various - * <code>Invoker</code> classes. - * - * @throws ConfigurationException An error occurred setting up the - * configuration in the <code>TransactionContext</code>. - */ - protected final void setUpContexts( String transactionID) throws ConfigurationException { - final TransactionContextManager txMgr = TransactionContextManager.getInstance(); - final LoggingContextManager logMgr = LoggingContextManager.getInstance(); + if (txMgr.getTransactionContext() == null) { + log.debug("Set not MOA-Sig transaction context"); + final TransactionContext ctx = + new TransactionContext(transactionID, null, ConfigurationProvider.getInstance()); + txMgr.setTransactionContext(ctx); - if (txMgr.getTransactionContext() == null) { - log.debug("Set not MOA-Sig transaction context"); - final TransactionContext ctx = new TransactionContext(transactionID, null, ConfigurationProvider.getInstance()); - txMgr.setTransactionContext(ctx); + } - } + if (logMgr.getLoggingContext() == null) { + final LoggingContext ctx = new LoggingContext(transactionID); + logMgr.setLoggingContext(ctx); - if (logMgr.getLoggingContext() == null) { - final LoggingContext ctx = new LoggingContext(transactionID); - logMgr.setLoggingContext(ctx); + } - } - - new IaikConfigurator().configure(ConfigurationProvider.getInstance()); + new IaikConfigurator().configure(ConfigurationProvider.getInstance()); - } + } - /** - * Tear down thread-local context information. - */ - protected void tearDownContexts() { - TransactionContextManager.getInstance().setTransactionContext(null); - LoggingContextManager.getInstance().setLoggingContext(null); - log.debug("Closing MOA-Sig transaction context"); + /** + * Tear down thread-local context information. + */ + protected void tearDownContexts() { + TransactionContextManager.getInstance().setTransactionContext(null); + LoggingContextManager.getInstance().setLoggingContext(null); + log.debug("Closing MOA-Sig transaction context"); - } + } } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MOASigSpringResourceProvider.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MOASigSpringResourceProvider.java deleted file mode 100644 index ecda7eb1..00000000 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MOASigSpringResourceProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import at.gv.egiz.components.spring.api.SpringResourceProvider; - -public class MOASigSpringResourceProvider implements SpringResourceProvider { - - @Override - public Resource[] getResourcesToLoad() { - ClassPathResource moaSigConfig = new ClassPathResource("/moa-sig-service.beans.xml", MOASigSpringResourceProvider.class); - return new Resource[] {moaSigConfig}; - } - - @Override - public String[] getPackagesToScan() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getName() { - return "Signature-verification service based on MOA-Sig (MOA-SPSS)"; - } - -} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigInitializer.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigInitializer.java index 1628b71a..f0ee4612 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigInitializer.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigInitializer.java @@ -6,11 +6,10 @@ import java.security.Provider; import java.security.Security; import java.util.Iterator; import java.util.Map.Entry; - import javax.annotation.Nonnull; import javax.annotation.PostConstruct; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.ISchemaRessourceProvider; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceConfigurationException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceConfigurationException; import at.gv.egovernment.moa.spss.MOAException; import at.gv.egovernment.moa.spss.api.Configurator; import at.gv.egovernment.moaspss.logging.LoggingContext; @@ -24,103 +23,108 @@ import iaik.security.ec.provider.ECCelerate; import iaik.security.provider.IAIK; public class MoaSigInitializer { - private static final Logger log = LoggerFactory.getLogger(MoaSigInitializer.class); - - @Autowired(required=false) ISchemaRessourceProvider[] schemas; - - private Configurator moaSigConfigurator; - - - /** - * Get MOA-Sig configuration object - * - * @return moa-sig configuration - */ - @Nonnull - public Configurator getMoaSigConfigurator() { - return moaSigConfigurator; - - } - - @PostConstruct - private synchronized void initialize() throws MOASigServiceConfigurationException { - log.info("Initializing MOA-Sig signature-verification service ... "); - - log.info("Loading Java security providers."); - IAIK.addAsProvider(); - ECCelerate.addAsProvider(); - - try { - LoggingContextManager.getInstance().setLoggingContext( - new LoggingContext("startup")); - log.debug("MOA-Sig library initialization process ... "); - Configurator.getInstance().init(); - log.info("MOA-Sig library initialization complete "); - - Security.insertProviderAt(IAIK.getInstance(), 0); - - final ECCelerate eccProvider = ECCelerate.getInstance(); - if (Security.getProvider(eccProvider.getName()) != null) - Security.removeProvider(eccProvider.getName()); - Security.addProvider(new ECCelerate()); - - fixJava8_141ProblemWithSSLAlgorithms(); - - if (log.isDebugEnabled()) { - log.debug("Loaded Security Provider:"); - final Provider[] providerList = Security.getProviders(); - for (int i=0; i<providerList.length; i++) - log.debug(i + ": " + providerList[i].getName() + " Version " + providerList[i].getVersion()); + private static final Logger log = LoggerFactory.getLogger(MoaSigInitializer.class); - } + @Autowired(required = false) + ISchemaRessourceProvider[] schemas; + + private Configurator moaSigConfigurator; + + + /** + * Get MOA-Sig configuration object. + * + * @return moa-sig configuration + */ + @Nonnull + public Configurator getMoaSigConfigurator() { + return moaSigConfigurator; + + } + + @PostConstruct + private synchronized void initialize() throws MoaSigServiceConfigurationException { + log.info("Initializing MOA-Sig signature-verification service ... "); + + log.info("Loading Java security providers."); + IAIK.addAsProvider(); + ECCelerate.addAsProvider(); + + try { + LoggingContextManager.getInstance().setLoggingContext(new LoggingContext("startup")); + log.debug("MOA-Sig library initialization process ... "); + Configurator.getInstance().init(); + log.info("MOA-Sig library initialization complete "); + + Security.insertProviderAt(IAIK.getInstance(), 0); + final ECCelerate eccProvider = ECCelerate.getInstance(); + if (Security.getProvider(eccProvider.getName()) != null) { + Security.removeProvider(eccProvider.getName()); + } + Security.addProvider(new ECCelerate()); - //Inject additional XML schemes - if (schemas != null && schemas.length > 0) { - log.debug("Infjecting additional XML schemes ... "); - for (final ISchemaRessourceProvider el : schemas) { - final Iterator<Entry<String, InputStream>> xmlSchemeIt = el.getSchemas().entrySet().iterator(); - while (xmlSchemeIt.hasNext()) { - final Entry<String, InputStream> xmlDef = xmlSchemeIt.next(); - try { - DOMUtils.addSchemaToPool(xmlDef.getValue(), xmlDef.getKey()); - log.info("Inject XML scheme: {}", xmlDef.getKey()); + fixJava8_141ProblemWithSslAlgorithms(); - } catch (final IOException e) { - log.warn("Can NOT inject XML scheme: " + xmlDef.getKey(), e); + if (log.isDebugEnabled()) { + log.debug("Loaded Security Provider:"); + final Provider[] providerList = Security.getProviders(); + for (int i = 0; i < providerList.length; i++) { + log.debug( + i + ": " + providerList[i].getName() + " Version " + providerList[i].getVersion()); + } - } + } + + + // Inject additional XML schemes + if (schemas != null && schemas.length > 0) { + log.debug("Infjecting additional XML schemes ... "); + for (final ISchemaRessourceProvider el : schemas) { + final Iterator<Entry<String, InputStream>> xmlSchemeIt = + el.getSchemas().entrySet().iterator(); + while (xmlSchemeIt.hasNext()) { + final Entry<String, InputStream> xmlDef = xmlSchemeIt.next(); + try { + DOMUtils.addSchemaToPool(xmlDef.getValue(), xmlDef.getKey()); + log.info("Inject XML scheme: {}", xmlDef.getKey()); + + } catch (final IOException e) { + log.warn("Can NOT inject XML scheme: " + xmlDef.getKey(), e); - } - } } - - moaSigConfigurator = Configurator.getInstance(); - - - } catch (final MOAException e) { - log.error("MOA-SP initialization FAILED!", e.getWrapped()); - throw new MOASigServiceConfigurationException("service.moasig.04", new Object[] { e - .toString() }, e); - } - - - } - - private static void fixJava8_141ProblemWithSSLAlgorithms() { - log.info("Change AlgorithmIDs to fix problems with Java8 >= 141 ..."); - //new AlgorithmID("1.2.840.113549.1.1.4", "md5WithRSAEncryption", new String[] { "MD5withRSA", "MD5/RSA", }, null, true); - new AlgorithmID("1.2.840.113549.1.1.5", "sha1WithRSAEncryption", - new String[] { "SHA1withRSA" , "SHA1/RSA", "SHA-1/RSA", "SHA/RSA", }, null, true); - new AlgorithmID("1.2.840.113549.1.1.14", "sha224WithRSAEncryption", - new String[] { "SHA224withRSA", "SHA224/RSA", "SHA-224/RSA", }, null, true); - new AlgorithmID("1.2.840.113549.1.1.11", "sha256WithRSAEncryption", - new String[] { "SHA256withRSA", "SHA256/RSA", "SHA-256/RSA", }, null, true); - new AlgorithmID("1.2.840.113549.1.1.12", "sha384WithRSAEncryption", - new String[] { "SHA384withRSA", "SHA384/RSA", "SHA-384/RSA", }, null, true); - new AlgorithmID("1.2.840.113549.1.1.13", "sha512WithRSAEncryption", - new String[] { "SHA512withRSA", "SHA512/RSA", "SHA-512/RSA" }, null, true); - - log.info("Change AlgorithmIDs finished"); + + } + } + } + + moaSigConfigurator = Configurator.getInstance(); + + + } catch (final MOAException e) { + log.error("MOA-SP initialization FAILED!", e.getWrapped()); + throw new MoaSigServiceConfigurationException("service.moasig.04", + new Object[] {e.toString()}, e); } + + + } + + private static void fixJava8_141ProblemWithSslAlgorithms() { + log.info("Change AlgorithmIDs to fix problems with Java8 >= 141 ..."); + // new AlgorithmID("1.2.840.113549.1.1.4", "md5WithRSAEncryption", new String[] { "MD5withRSA", + // "MD5/RSA", }, null, true); + new AlgorithmID("1.2.840.113549.1.1.5", "sha1WithRSAEncryption", + new String[] {"SHA1withRSA", "SHA1/RSA", "SHA-1/RSA", "SHA/RSA",}, null, true); + new AlgorithmID("1.2.840.113549.1.1.14", "sha224WithRSAEncryption", + new String[] {"SHA224withRSA", "SHA224/RSA", "SHA-224/RSA",}, null, true); + new AlgorithmID("1.2.840.113549.1.1.11", "sha256WithRSAEncryption", + new String[] {"SHA256withRSA", "SHA256/RSA", "SHA-256/RSA",}, null, true); + new AlgorithmID("1.2.840.113549.1.1.12", "sha384WithRSAEncryption", + new String[] {"SHA384withRSA", "SHA384/RSA", "SHA-384/RSA",}, null, true); + new AlgorithmID("1.2.840.113549.1.1.13", "sha512WithRSAEncryption", + new String[] {"SHA512withRSA", "SHA512/RSA", "SHA-512/RSA"}, null, true); + + log.info("Change AlgorithmIDs finished"); + } } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java new file mode 100644 index 00000000..c8275264 --- /dev/null +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java @@ -0,0 +1,28 @@ +package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class MoaSigSpringResourceProvider implements SpringResourceProvider { + + @Override + public Resource[] getResourcesToLoad() { + final ClassPathResource moaSigConfig = + new ClassPathResource("/moa-sig-service.beans.xml", MoaSigSpringResourceProvider.class); + return new Resource[] {moaSigConfig}; + } + + @Override + public String[] getPackagesToScan() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getName() { + return "Signature-verification service based on MOA-Sig (MOA-SPSS)"; + } + +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureCreationService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureCreationService.java index 59e7b516..5cb001ef 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureCreationService.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureCreationService.java @@ -10,21 +10,22 @@ import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.ISignatureCreatio import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureCreationInvoker; import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker; -@Service(value="moaSigCreateService") -public class SignatureCreationService extends AbstractSignatureService implements ISignatureCreationService{ - private static final Logger log = LoggerFactory.getLogger(SignatureCreationService.class); - - private XMLSignatureCreationInvoker xadesInvoker; - private CMSSignatureCreationInvoker cadesInvoker; - - - @PostConstruct - protected void internalInitializer() { - log.debug("Instanzing SignatureCreationService implementation ... "); - xadesInvoker = XMLSignatureCreationInvoker.getInstance(); - cadesInvoker = CMSSignatureCreationInvoker.getInstance(); - log.info("MOA-Sig signature-creation service initialized"); - - } +@Service(value = "moaSigCreateService") +public class SignatureCreationService extends AbstractSignatureService + implements ISignatureCreationService { + private static final Logger log = LoggerFactory.getLogger(SignatureCreationService.class); + + private XMLSignatureCreationInvoker xadesInvoker; + private CMSSignatureCreationInvoker cadesInvoker; + + + @PostConstruct + protected void internalInitializer() { + log.debug("Instanzing SignatureCreationService implementation ... "); + xadesInvoker = XMLSignatureCreationInvoker.getInstance(); + cadesInvoker = CMSSignatureCreationInvoker.getInstance(); + log.info("MOA-Sig signature-creation service initialized"); + + } } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureVerificationService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureVerificationService.java index f610e59e..3dbda391 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureVerificationService.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/SignatureVerificationService.java @@ -7,9 +7,9 @@ import javax.annotation.PostConstruct; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.ISignatureVerificationService; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.ICMSSignatureVerificationResponse; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IXMLSignatureVerificationResponse; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceBuilderException; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceException; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.parser.VerifyXMLSignatureResponseParser; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceBuilderException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.parser.VerifyXmlSignatureResponseParser; import at.gv.egovernment.moa.spss.MOAException; import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; @@ -33,270 +33,321 @@ import org.w3c.dom.Node; /** + * MOA-Sig based signature verification implementation. + * * @author tlenz * */ -@Service(value="moaSigVerifyService") -public class SignatureVerificationService extends AbstractSignatureService implements ISignatureVerificationService { - private static final Logger log = LoggerFactory.getLogger(SignatureVerificationService.class); - - private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; - private static final String MOA_NS_URI = Constants.MOA_NS_URI; - private static final String DSIG = Constants.DSIG_PREFIX + ":"; - private static final String DEFAULT_XPATH_SIGNATURE_LOCATION = "//" + DSIG + "Signature"; - - private CMSSignatureVerificationInvoker cadesInvoker; - private XMLSignatureVerificationInvoker xadesInvocer; - - /* (non-Javadoc) - * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService#verifyCMSSignature(byte[], java.lang.String) - */ - @Override - @Nullable - public ICMSSignatureVerificationResponse verifyCMSSignature(byte[] signature, String trustProfileID) throws MOASigServiceException { - try { - //setup context - setUpContexts(Thread.currentThread().getName()); - - //verify signature - final VerifyCMSSignatureRequest cmsSigVerifyReq = buildVerfifyCMSRequest(signature, trustProfileID, false, false); - final VerifyCMSSignatureResponse cmsSigVerifyResp = cadesInvoker.verifyCMSSignature(cmsSigVerifyReq ); - return parseCMSVerificationResult(cmsSigVerifyResp); - - } catch (final MOAException e) { - log.warn("CMS signature verification has an error.", e); - throw new MOASigServiceException("service.03", new Object[] { e.toString()}, e); - - } catch (final CertificateEncodingException e) { - log.warn("Can NOT serialize X509 certificate from CMS/CAdES signature-verification response", e); - throw new MOASigServiceException("service.03", new Object[] { e.toString()}, e); - - } finally { - tearDownContexts(); +@Service(value = "moaSigVerifyService") +public class SignatureVerificationService extends AbstractSignatureService + implements ISignatureVerificationService { + private static final Logger log = LoggerFactory.getLogger(SignatureVerificationService.class); + + private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; + private static final String MOA_NS_URI = Constants.MOA_NS_URI; + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + private static final String DEFAULT_XPATH_SIGNATURE_LOCATION = "//" + DSIG + "Signature"; + + private CMSSignatureVerificationInvoker cadesInvoker; + private XMLSignatureVerificationInvoker xadesInvocer; + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService# + * verifyCMSSignature(byte[], java.lang.String) + */ + @Override + @Nullable + public ICMSSignatureVerificationResponse verifyCmsSignature(final byte[] signature, + final String trustProfileID) throws MoaSigServiceException { + try { + // setup context + setUpContexts(Thread.currentThread().getName()); + + // verify signature + final VerifyCMSSignatureRequest cmsSigVerifyReq = + buildVerfifyCmsRequest(signature, trustProfileID, false, false); + final VerifyCMSSignatureResponse cmsSigVerifyResp = + cadesInvoker.verifyCMSSignature(cmsSigVerifyReq); + return parseCmsVerificationResult(cmsSigVerifyResp); + + } catch (final MOAException e) { + log.warn("CMS signature verification has an error.", e); + throw new MoaSigServiceException("service.03", new Object[] {e.toString()}, e); + + } catch (final CertificateEncodingException e) { + log.warn("Can NOT serialize X509 certificate from CMS/CAdES signature-verification response", + e); + throw new MoaSigServiceException("service.03", new Object[] {e.toString()}, e); + + } finally { + tearDownContexts(); + + } + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService# + * verifyXMLSignature(byte[], java.lang.String) + */ + @Override + public IXMLSignatureVerificationResponse verifyXmlSignature(final byte[] signature, + final String trustProfileID) throws MoaSigServiceException { + return verifyXmlSignature(signature, trustProfileID, null, DEFAULT_XPATH_SIGNATURE_LOCATION); + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService# + * verifyXMLSignature(byte[], java.lang.String, java.util.List) + */ + @Override + public IXMLSignatureVerificationResponse verifyXmlSignature(final byte[] signature, + final String trustProfileID, final List<String> verifyTransformsInfoProfileID) + throws MoaSigServiceException { + return verifyXmlSignature(signature, trustProfileID, verifyTransformsInfoProfileID, + DEFAULT_XPATH_SIGNATURE_LOCATION); + } + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService# + * verifyXMLSignature(byte[], java.lang.String, java.lang.String) + */ + @Override + public IXMLSignatureVerificationResponse verifyXmlSignature(final byte[] signature, + final String trustProfileID, final String signatureLocationXpath) + throws MoaSigServiceException { + return verifyXmlSignature(signature, trustProfileID, null, signatureLocationXpath); + } + + /* + * (non-Javadoc) + * + * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService# + * verifyXMLSignature(byte[], java.lang.String, java.util.List, java.lang.String) + */ + @Override + public IXMLSignatureVerificationResponse verifyXmlSignature(final byte[] signature, + final String trustProfileID, final List<String> verifyTransformsInfoProfileID, + final String xpathSignatureLocation) throws MoaSigServiceException { + try { + // setup context + setUpContexts(Thread.currentThread().getName()); + + // build signature-verification request + final Element domVerifyXmlSignatureRequest = buildVerifyXmlRequest(signature, trustProfileID, + verifyTransformsInfoProfileID, xpathSignatureLocation); + + // send signature-verification to MOA-Sig + final VerifyXMLSignatureRequest vsrequest = + new VerifyXMLSignatureRequestParser().parse(domVerifyXmlSignatureRequest); + final VerifyXMLSignatureResponse vsresponse = xadesInvocer.verifyXMLSignature(vsrequest); + final Document result = new VerifyXMLSignatureResponseBuilder(true).build(vsresponse); + + // parses the <IXMLSignatureVerificationResponse> + final IXMLSignatureVerificationResponse verifyXmlSignatureResponse = + new VerifyXmlSignatureResponseParser(result.getDocumentElement()).parseData(); + + return verifyXmlSignatureResponse; + + } catch (final MoaSigServiceException e) { + throw e; + + } catch (final MOAException e) { + log.warn("MOA-Sig signature-verification has an internal error." + " MsgCode: " + + e.getMessageId() + " Msg: " + e.getMessage(), e); + throw new MoaSigServiceException("service.moasig.03", new Object[] {e.getMessage()}, e); + + } finally { + tearDownContexts(); + + } + } + + private ICMSSignatureVerificationResponse parseCmsVerificationResult( + final VerifyCMSSignatureResponse cmsSigVerifyResp) throws CertificateEncodingException { + + if (cmsSigVerifyResp.getResponseElements() == null + || cmsSigVerifyResp.getResponseElements().isEmpty()) { + log.info("No CMS signature FOUND. "); + return null; + + } + + if (cmsSigVerifyResp.getResponseElements().size() > 1) { + log.warn( + "CMS or CAdES signature contains more than one technical signatures. Only validate the first signature"); + } + + final VerifyCMSSignatureResponseElement firstSig = + (VerifyCMSSignatureResponseElement) cmsSigVerifyResp.getResponseElements().get(0); + + final at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data.VerifyCMSSignatureResponse result = + new at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data.VerifyCMSSignatureResponse(); + + // parse results into response container + result.setSignatureCheckCode(firstSig.getSignatureCheck().getCode()); + result.setCertificateCheckCode(firstSig.getCertificateCheck().getCode()); + + if (firstSig.getSignerInfo() != null) { + result.setSigningDateTime(firstSig.getSignerInfo().getSigningTime()); + result + .setX509CertificateEncoded(firstSig.getSignerInfo().getSignerCertificate().getEncoded()); + result.setQualifiedCertificate(firstSig.getSignerInfo().isQualifiedCertificate()); + + result.setPublicAuthority(firstSig.getSignerInfo().isPublicAuthority()); + result.setPublicAuthorityCode(firstSig.getSignerInfo().getPublicAuhtorityID()); + + } else { + log.info("CMS or CAdES verification result contains no SignerInfo"); + } + + return result; + } + + /** + * Build a VerifyCMS-Siganture request for MOA-Sig. <br> + * <br> + * This builder only generates verification-request for enveloped CMS or CAdES signatures <br> + * This + * + * @param signature CMS or CAdES signature + * @param trustProfileID trustProfileID MOA-Sig Trust-Profile + * @param isPdfSignature Make CAdES signature as part of an PAdES document + * @param performExtendedValidation To extended validation. See MOA-Sig documentation for detailed + * information + * @return + */ + private VerifyCMSSignatureRequest buildVerfifyCmsRequest(final byte[] signature, + final String trustProfileID, final boolean isPdfSignature, + final boolean performExtendedValidation) { + final VerifyCMSSignatureRequestImpl verifyCmsSignatureRequest = + new VerifyCMSSignatureRequestImpl(); + verifyCmsSignatureRequest.setDateTime(null); + verifyCmsSignatureRequest.setCMSSignature(new ByteArrayInputStream(signature)); + verifyCmsSignatureRequest.setDataObject(null); + verifyCmsSignatureRequest.setTrustProfileId(trustProfileID); + verifyCmsSignatureRequest.setSignatories(VerifyCMSSignatureRequest.ALL_SIGNATORIES); + verifyCmsSignatureRequest.setPDF(isPdfSignature); + verifyCmsSignatureRequest.setExtended(performExtendedValidation); + return verifyCmsSignatureRequest; + + } + + /** + * Build a VerifyXML-Signature request for MOA-Sig. + * + * @param signature Serialized XML signature + * @param trustProfileID MOA-Sig Trust-Profile + * @param verifyTransformsInfoProfileID {@link List} of Transformation-Profiles used for + * validation + * @param xpathSignatureLocation Xpath that points to location of Signature element + * @return MOA-Sig verification request element + * @throws MoaSigServiceBuilderException In case of an error + */ + private Element buildVerifyXmlRequest(final byte[] signature, final String trustProfileID, + final List<String> verifyTransformsInfoProfileID, final String xpathSignatureLocation) + throws MoaSigServiceBuilderException { + try { + // build empty document + final Document requestDoc_ = getNewDocumentBuilder(); + final Element requestElem_ = + requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); + requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); + requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, + Constants.DSIG_NS_URI); + requestDoc_.appendChild(requestElem_); + + + // build the request + final Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + final Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + final Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); + verifySignatureEnvironmentElem.appendChild(base64ContentElem); + + // insert the base64 encoded signature + String base64EncodedAssertion = Base64Utils.encodeToString(signature); + // replace all '\r' characters by no char. + final StringBuffer replaced = new StringBuffer(); + for (int i = 0; i < base64EncodedAssertion.length(); i++) { + final char c = base64EncodedAssertion.charAt(i); + if (c != '\r') { + replaced.append(c); + } + } + base64EncodedAssertion = replaced.toString(); + final Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); + base64ContentElem.appendChild(base64Content); + + // specify the signature location + final Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + final Node signatureLocation = requestDoc_.createTextNode(xpathSignatureLocation); + verifySignatureLocationElem.appendChild(signatureLocation); + + // signature manifest params + if (verifyTransformsInfoProfileID != null && !verifyTransformsInfoProfileID.isEmpty()) { + final Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); + + // verify transformations + final Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + for (final String element : verifyTransformsInfoProfileID) { + final Element verifyTransformsInfoProfileIdElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileIdElem); + verifyTransformsInfoProfileIdElem.appendChild(requestDoc_.createTextNode(element)); } + } - } - - /* (non-Javadoc) - * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService#verifyXMLSignature(byte[], java.lang.String) - */ - @Override - public IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID) throws MOASigServiceException { - return verifyXMLSignature(signature, trustProfileID, null, DEFAULT_XPATH_SIGNATURE_LOCATION); - - } - - /* (non-Javadoc) - * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService#verifyXMLSignature(byte[], java.lang.String, java.util.List) - */ - @Override - public IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID) throws MOASigServiceException { - return verifyXMLSignature(signature, trustProfileID, verifyTransformsInfoProfileID, DEFAULT_XPATH_SIGNATURE_LOCATION); - } - - /* (non-Javadoc) - * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService#verifyXMLSignature(byte[], java.lang.String, java.lang.String) - */ - @Override - public IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID, String signatureLocationXpath) throws MOASigServiceException { - return verifyXMLSignature(signature, trustProfileID, null, signatureLocationXpath); - } - - /* (non-Javadoc) - * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.ISignatureVerificationService#verifyXMLSignature(byte[], java.lang.String, java.util.List, java.lang.String) - */ - @Override - public IXMLSignatureVerificationResponse verifyXMLSignature(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID, String xpathSignatureLocation) throws MOASigServiceException { - try { - //setup context - setUpContexts(Thread.currentThread().getName()); - - //build signature-verification request - final Element domVerifyXMLSignatureRequest = buildVerifyXMLRequest(signature, trustProfileID, verifyTransformsInfoProfileID, xpathSignatureLocation); - - //send signature-verification to MOA-Sig - final VerifyXMLSignatureRequest vsrequest = new VerifyXMLSignatureRequestParser().parse(domVerifyXMLSignatureRequest); - final VerifyXMLSignatureResponse vsresponse = xadesInvocer.verifyXMLSignature(vsrequest); - final Document result = new VerifyXMLSignatureResponseBuilder(true).build(vsresponse); - - // parses the <IXMLSignatureVerificationResponse> - final IXMLSignatureVerificationResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser(result.getDocumentElement()).parseData(); - - return verifyXMLSignatureResponse; - - } catch (final MOASigServiceException e) { - throw e; - - } catch (final MOAException e) { - log.warn("MOA-Sig signature-verification has an internal error." - + " MsgCode: " + e.getMessageId() - + " Msg: " + e.getMessage(), - e); - throw new MOASigServiceException("service.moasig.03", new Object[]{e.getMessage()}, e); - - } finally { - tearDownContexts(); + // hashinput data + final Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); - } - } - -private ICMSSignatureVerificationResponse parseCMSVerificationResult(VerifyCMSSignatureResponse cmsSigVerifyResp) throws CertificateEncodingException { - - if (cmsSigVerifyResp.getResponseElements() == null || - cmsSigVerifyResp.getResponseElements().isEmpty()) { - log.info("No CMS signature FOUND. "); - return null; - - } - - if (cmsSigVerifyResp.getResponseElements().size() > 1) - log.warn("CMS or CAdES signature contains more than one technical signatures. Only validate the first signature"); - - final VerifyCMSSignatureResponseElement firstSig = (VerifyCMSSignatureResponseElement) cmsSigVerifyResp.getResponseElements().get(0); - - final at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data.VerifyCMSSignatureResponse result = - new at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data.VerifyCMSSignatureResponse(); - - //parse results into response container - result.setSignatureCheckCode(firstSig.getSignatureCheck().getCode()); - result.setCertificateCheckCode(firstSig.getCertificateCheck().getCode()); - - if (firstSig.getSignerInfo() != null) { - result.setSigningDateTime(firstSig.getSignerInfo().getSigningTime()); - result.setX509CertificateEncoded(firstSig.getSignerInfo().getSignerCertificate().getEncoded()); - result.setQualifiedCertificate(firstSig.getSignerInfo().isQualifiedCertificate()); - - result.setPublicAuthority(firstSig.getSignerInfo().isPublicAuthority()); - result.setPublicAuthorityCode(firstSig.getSignerInfo().getPublicAuhtorityID()); - - } else - log.info("CMS or CAdES verification result contains no SignerInfo"); - - return result; - } - - /** - * Build a VerifyCMS-Siganture request for MOA-Sig. - * <br><br> - * This builder only generates verification-request for enveloped CMS or CAdES signatures - * <br> - * This - * - * @param signature CMS or CAdES signature - * @param trustProfileID trustProfileID MOA-Sig Trust-Profile - * @param isPdfSignature Make CAdES signature as part of an PAdES document - * @param performExtendedValidation To extended validation. See MOA-Sig documentation for detailed information - * @return - */ - private VerifyCMSSignatureRequest buildVerfifyCMSRequest(byte[] signature, String trustProfileID, - boolean isPdfSignature, boolean performExtendedValidation) { - final VerifyCMSSignatureRequestImpl verifyCMSSignatureRequest = new VerifyCMSSignatureRequestImpl(); - verifyCMSSignatureRequest.setDateTime(null); - verifyCMSSignatureRequest.setCMSSignature(new ByteArrayInputStream(signature)); - verifyCMSSignatureRequest.setDataObject(null); - verifyCMSSignatureRequest.setTrustProfileId(trustProfileID); - verifyCMSSignatureRequest.setSignatories(VerifyCMSSignatureRequest.ALL_SIGNATORIES); - verifyCMSSignatureRequest.setPDF(isPdfSignature); - verifyCMSSignatureRequest.setExtended(performExtendedValidation); - return verifyCMSSignatureRequest; - - } - - /** - * Build a VerifyXML-Signature request for MOA-Sig - * - * @param signature Serialized XML signature - * @param trustProfileID MOA-Sig Trust-Profile - * @param verifyTransformsInfoProfileID {@link List} of Transformation-Profiles used for validation - * @param xpathSignatureLocation Xpath that points to location of Signature element - * @return - * @throws MOASigServiceBuilderException - */ - private Element buildVerifyXMLRequest(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID, String xpathSignatureLocation) throws MOASigServiceBuilderException { - try { - //build empty document - final Document requestDoc_ = getNewDocumentBuilder(); - final Element requestElem_ = requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); - requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); - requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); - requestDoc_.appendChild(requestElem_); - - - // build the request - final Element verifiySignatureInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); - requestElem_.appendChild(verifiySignatureInfoElem); - final Element verifySignatureEnvironmentElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); - verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); - final Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); - verifySignatureEnvironmentElem.appendChild(base64ContentElem); - - // insert the base64 encoded signature - String base64EncodedAssertion = Base64Utils.encodeToString(signature); - //replace all '\r' characters by no char. - final StringBuffer replaced = new StringBuffer(); - for (int i = 0; i < base64EncodedAssertion.length(); i ++) { - final char c = base64EncodedAssertion.charAt(i); - if (c != '\r') { - replaced.append(c); - } - } - base64EncodedAssertion = replaced.toString(); - final Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); - base64ContentElem.appendChild(base64Content); - - // specify the signature location - final Element verifySignatureLocationElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); - verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); - final Node signatureLocation = requestDoc_.createTextNode(xpathSignatureLocation); - verifySignatureLocationElem.appendChild(signatureLocation); - - // signature manifest params - if (verifyTransformsInfoProfileID != null && !verifyTransformsInfoProfileID.isEmpty()) { - final Element signatureManifestCheckParamsElem = requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); - requestElem_.appendChild(signatureManifestCheckParamsElem); - signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); - - //verify transformations - final Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); - signatureManifestCheckParamsElem.appendChild(referenceInfoElem); - for (final String element : verifyTransformsInfoProfileID) { - final Element verifyTransformsInfoProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); - referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); - verifyTransformsInfoProfileIDElem.appendChild(requestDoc_.createTextNode(element)); - - } - } - - //hashinput data - final Element returnHashInputDataElem = requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); - requestElem_.appendChild(returnHashInputDataElem); - - //add trustProfileID - final Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); - trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); - requestElem_.appendChild(trustProfileIDElem); - - return requestElem_; - - } catch (final Throwable t) { - log.warn("Can NOT build VerifyXML-Signature request for MOA-Sig", t); - throw new MOASigServiceBuilderException("service.moasig.03", new Object[] { t.getMessage() }, t); - - } - - } - - - - @PostConstruct - protected void internalInitializer() { - log.debug("Instanzing SignatureVerificationService implementation ... "); - //svs = at.gv.egovernment.moa.spss.api.SignatureVerificationService.getInstance(); - cadesInvoker = CMSSignatureVerificationInvoker.getInstance(); - xadesInvocer = XMLSignatureVerificationInvoker.getInstance(); - log.info("MOA-Sig signature-verification service initialized"); - - } + // add trustProfileID + final Element trustProfileIdElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIdElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIdElem); + + return requestElem_; + + } catch (final Throwable t) { + log.warn("Can NOT build VerifyXML-Signature request for MOA-Sig", t); + throw new MoaSigServiceBuilderException("service.moasig.03", new Object[] {t.getMessage()}, + t); + + } + + } + + + + @PostConstruct + protected void internalInitializer() { + log.debug("Instanzing SignatureVerificationService implementation ... "); + // svs = at.gv.egovernment.moa.spss.api.SignatureVerificationService.getInstance(); + cadesInvoker = CMSSignatureVerificationInvoker.getInstance(); + xadesInvocer = XMLSignatureVerificationInvoker.getInstance(); + log.info("MOA-Sig signature-verification service initialized"); + + } } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java index f3c724d8..701e2072 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java @@ -9,122 +9,125 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IGenericSignatureVerificationResponse; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceException; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceParserException; - -public class GenericSignatureVerificationResponse implements IGenericSignatureVerificationResponse, Serializable { - - private static final long serialVersionUID = -7751001050689401118L; - private static final Logger log = LoggerFactory.getLogger(GenericSignatureVerificationResponse.class); - - - /** The signing time */ - private Date signingDateTime; - - /** The signatureCheckCode to be stored */ - private int signatureCheckCode; - - /** The certificateCheckCode to be stored */ - private int certificateCheckCode; - - /** The publicAuthority to be stored */ - private boolean publicAuthority; - - /** The publicAuthorityCode to be stored */ - private String publicAuthorityCode; - - /** The qualifiedCertificate to be stored */ - private boolean qualifiedCertificate; - - private byte[] x509CertificateEncoded; - - @Override - public Date getSigningDateTime() { - return this.signingDateTime; - - } - - @Override - public int getSignatureCheckCode() { - return this.signatureCheckCode; - - } - - @Override - public int getCertificateCheckCode() { - return this.certificateCheckCode; - - } - - @Override - public boolean isQualifiedCertificate() { - return this.qualifiedCertificate; - - } - - @Override - public X509Certificate getX509Certificate() throws MOASigServiceException { - if (x509CertificateEncoded != null) { - try { - return new X509Certificate(x509CertificateEncoded); - - } catch (CertificateException e) { - log.error("Can NOT parse X509 certifcate in " + GenericSignatureVerificationResponse.class.getName(), e); - throw new MOASigServiceParserException("service.moasig.01", null, e); - } - - } - - return null; - - } - - @Override - public byte[] getX509CertificateEncoded() { - return this.getX509CertificateEncoded(); - - } - - @Override - public boolean isPublicAuthority() { - return this.publicAuthority; - - } - - @Override - public String getPublicAuthorityCode() { - return this.publicAuthorityCode; - - } - - public void setSigningDateTime(Date signingDateTime) { - this.signingDateTime = signingDateTime; - } - - public void setSignatureCheckCode(int signatureCheckCode) { - this.signatureCheckCode = signatureCheckCode; - } - - public void setCertificateCheckCode(int certificateCheckCode) { - this.certificateCheckCode = certificateCheckCode; - } - - public void setPublicAuthority(boolean publicAuthority) { - this.publicAuthority = publicAuthority; - } - - public void setPublicAuthorityCode(String publicAuthorityCode) { - this.publicAuthorityCode = publicAuthorityCode; - } - - public void setQualifiedCertificate(boolean qualifiedCertificate) { - this.qualifiedCertificate = qualifiedCertificate; - } - - public void setX509CertificateEncoded(byte[] x509CertificateEncoded) { - this.x509CertificateEncoded = x509CertificateEncoded; - } - - +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceParserException; + +public class GenericSignatureVerificationResponse + implements IGenericSignatureVerificationResponse, Serializable { + + private static final long serialVersionUID = -7751001050689401118L; + private static final Logger log = + LoggerFactory.getLogger(GenericSignatureVerificationResponse.class); + + + /** The signing time */ + private Date signingDateTime; + + /** The signatureCheckCode to be stored */ + private int signatureCheckCode; + + /** The certificateCheckCode to be stored */ + private int certificateCheckCode; + + /** The publicAuthority to be stored */ + private boolean publicAuthority; + + /** The publicAuthorityCode to be stored */ + private String publicAuthorityCode; + + /** The qualifiedCertificate to be stored */ + private boolean qualifiedCertificate; + + private byte[] x509CertificateEncoded; + + @Override + public Date getSigningDateTime() { + return this.signingDateTime; + + } + + @Override + public int getSignatureCheckCode() { + return this.signatureCheckCode; + + } + + @Override + public int getCertificateCheckCode() { + return this.certificateCheckCode; + + } + + @Override + public boolean isQualifiedCertificate() { + return this.qualifiedCertificate; + + } + + @Override + public X509Certificate getX509Certificate() throws MoaSigServiceException { + if (x509CertificateEncoded != null) { + try { + return new X509Certificate(x509CertificateEncoded); + + } catch (final CertificateException e) { + log.error("Can NOT parse X509 certifcate in " + + GenericSignatureVerificationResponse.class.getName(), e); + throw new MoaSigServiceParserException("service.moasig.01", null, e); + } + + } + + return null; + + } + + @Override + public byte[] getX509CertificateEncoded() { + return this.getX509CertificateEncoded(); + + } + + @Override + public boolean isPublicAuthority() { + return this.publicAuthority; + + } + + @Override + public String getPublicAuthorityCode() { + return this.publicAuthorityCode; + + } + + public void setSigningDateTime(final Date signingDateTime) { + this.signingDateTime = signingDateTime; + } + + public void setSignatureCheckCode(final int signatureCheckCode) { + this.signatureCheckCode = signatureCheckCode; + } + + public void setCertificateCheckCode(final int certificateCheckCode) { + this.certificateCheckCode = certificateCheckCode; + } + + public void setPublicAuthority(final boolean publicAuthority) { + this.publicAuthority = publicAuthority; + } + + public void setPublicAuthorityCode(final String publicAuthorityCode) { + this.publicAuthorityCode = publicAuthorityCode; + } + + public void setQualifiedCertificate(final boolean qualifiedCertificate) { + this.qualifiedCertificate = qualifiedCertificate; + } + + public void setX509CertificateEncoded(final byte[] x509CertificateEncoded) { + this.x509CertificateEncoded = x509CertificateEncoded; + } + + } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyCMSSignatureResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyCMSSignatureResponse.java index 2c177c71..0583a29e 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyCMSSignatureResponse.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyCMSSignatureResponse.java @@ -2,8 +2,9 @@ package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.ICMSSignatureVerificationResponse; -public class VerifyCMSSignatureResponse extends GenericSignatureVerificationResponse implements ICMSSignatureVerificationResponse{ +public class VerifyCMSSignatureResponse extends GenericSignatureVerificationResponse + implements ICMSSignatureVerificationResponse { - private static final long serialVersionUID = 708260904158070696L; + private static final long serialVersionUID = 708260904158070696L; } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyXMLSignatureResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyXMLSignatureResponse.java index 0646bda7..003d2c46 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyXMLSignatureResponse.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/data/VerifyXMLSignatureResponse.java @@ -3,17 +3,18 @@ package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data; import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IXMLSignatureVerificationResponse; /** - * - * + * + * * @author tlenz * */ -public class VerifyXMLSignatureResponse extends GenericSignatureVerificationResponse implements IXMLSignatureVerificationResponse { +public class VerifyXMLSignatureResponse extends GenericSignatureVerificationResponse + implements IXMLSignatureVerificationResponse { private static final long serialVersionUID = 8386070769565711601L; -/** The xmlDsigSubjectName to be stored */ + /** The xmlDsigSubjectName to be stored */ private String xmlDsigSubjectName; /** The xmlDSIGManifestCheckCode to be stored */ @@ -22,72 +23,97 @@ public class VerifyXMLSignatureResponse extends GenericSignatureVerificationResp private boolean xmlDSIGManigest; /** - * The result of the signature manifest check. The default value <code>-1</code> - * indicates that the signature manifest has not been checked. + * The result of the signature manifest check. The default value <code>-1</code> indicates that + * the signature manifest has not been checked. */ private int signatureManifestCheckCode = -1; - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#getXmlDSIGManifestCheckCode() - */ + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#getXmlDSIGManifestCheckCode() + */ @Override -public int getXmlDSIGManifestCheckCode() { + public int getXmlDSIGManifestCheckCode() { return xmlDSIGManifestCheckCode; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#getXmlDsigSubjectName() - */ + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#getXmlDsigSubjectName() + */ @Override -public String getXmlDsigSubjectName() { + public String getXmlDsigSubjectName() { return xmlDsigSubjectName; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setXmlDSIGManifestCheckCode(int) - */ -public void setXmlDSIGManifestCheckCode(int xmlDSIGManifestCheckCode) { + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setXmlDSIGManifestCheckCode( + * int) + */ + public void setXmlDSIGManifestCheckCode(final int xmlDSIGManifestCheckCode) { this.xmlDSIGManifestCheckCode = xmlDSIGManifestCheckCode; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setXmlDsigSubjectName(java.lang.String) - */ -public void setXmlDsigSubjectName(String xmlDsigSubjectName) { + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setXmlDsigSubjectName(java.lang + * .String) + */ + public void setXmlDsigSubjectName(final String xmlDsigSubjectName) { this.xmlDsigSubjectName = xmlDsigSubjectName; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#isXmlDSIGManigest() - */ + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#isXmlDSIGManigest() + */ @Override -public boolean isXmlDSIGManigest() { + public boolean isXmlDSIGManigest() { return xmlDSIGManigest; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setXmlDSIGManigest(boolean) - */ -public void setXmlDSIGManigest(boolean xmlDSIGManigest) { + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setXmlDSIGManigest(boolean) + */ + public void setXmlDSIGManigest(final boolean xmlDSIGManigest) { this.xmlDSIGManigest = xmlDSIGManigest; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#getSignatureManifestCheckCode() - */ + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#getSignatureManifestCheckCode() + */ @Override -public int getSignatureManifestCheckCode() { + public int getSignatureManifestCheckCode() { return signatureManifestCheckCode; } - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setSignatureManifestCheckCode(int) - */ -public void setSignatureManifestCheckCode(int signatureManifestCheckCode) { + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.data.IVerifiyXMLSignatureResponse#setSignatureManifestCheckCode( + * int) + */ + public void setSignatureManifestCheckCode(final int signatureManifestCheckCode) { this.signatureManifestCheckCode = signatureManifestCheckCode; } - + } diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/parser/VerifyXMLSignatureResponseParser.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/parser/VerifyXMLSignatureResponseParser.java deleted file mode 100644 index e581394b..00000000 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/parser/VerifyXMLSignatureResponseParser.java +++ /dev/null @@ -1,180 +0,0 @@ -package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.parser; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -import org.joda.time.DateTime; -import org.joda.time.format.ISODateTimeFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.lang.NonNull; -import org.w3c.dom.Element; - -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IXMLSignatureVerificationResponse; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceException; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MOASigServiceParserException; -import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data.VerifyXMLSignatureResponse; -import at.gv.egovernment.moaspss.util.Constants; -import at.gv.egovernment.moaspss.util.DOMUtils; -import at.gv.egovernment.moaspss.util.XPathUtils; -import iaik.utils.Base64InputStream; -import iaik.x509.X509Certificate; - - -public class VerifyXMLSignatureResponseParser { - private static final Logger log = LoggerFactory.getLogger(VerifyXMLSignatureResponseParser.class); - - // - // XPath namespace prefix shortcuts - // - /** Xpath prefix for reaching MOA Namespaces */ - private static final String MOA = Constants.MOA_PREFIX + ":"; - /** Xpath prefix for reaching DSIG Namespaces */ - private static final String DSIG = Constants.DSIG_PREFIX + ":"; - /** Xpath expression to the root element */ - private static final String ROOT = "/" + MOA + "VerifyXMLSignatureResponse/"; - - /** Xpath expression to the X509SubjectName element */ - private static final String DSIG_SUBJECT_NAME_XPATH = - ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + - DSIG + "X509SubjectName"; - /** Xpath expression to the X509Certificate element */ - private static final String DSIG_X509_CERTIFICATE_XPATH = - ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + - DSIG + "X509Certificate"; - /** Xpath expression to the PublicAuthority element */ - private static final String PUBLIC_AUTHORITY_XPATH = - ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + - MOA + "PublicAuthority"; - /** Xpath expression to the PublicAuthorityCode element */ - private static final String PUBLIC_AUTHORITY_CODE_XPATH = - PUBLIC_AUTHORITY_XPATH + "/" + MOA + "Code"; - /** Xpath expression to the QualifiedCertificate element */ - private static final String QUALIFIED_CERTIFICATE_XPATH = - ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + - MOA + "QualifiedCertificate"; - - /** Xpath expression to the SignatureCheckCode element */ - private static final String SIGNATURE_CHECK_CODE_XPATH = - ROOT + MOA + "SignatureCheck/" + MOA + "Code"; - /** Xpath expression to the XMLDSIGManifestCheckCode element */ - private static final String XMLDSIG_MANIFEST_CHECK_CODE_XPATH = - ROOT + MOA + "XMLDSIGManifestCheck/" + MOA + "Code"; - /** Xpath expression to the SignatureManifestCheckCode element */ - private static final String SIGNATURE_MANIFEST_CHECK_CODE_XPATH = - ROOT + MOA + "SignatureManifestCheck/" + MOA + "Code"; - /** Xpath expression to the CertificateCheckCode element */ - private static final String CERTIFICATE_CHECK_CODE_XPATH = - ROOT + MOA + "CertificateCheck/" + MOA + "Code"; - - private static final String SIGNING_TIME_XPATH = - ROOT + MOA + "SigningTime"; - - - /** This is the root element of the XML-Document provided by the Security Layer Card*/ - private Element verifyXMLSignatureResponse; - - /** - * Constructor for VerifyXMLSignatureResponseParser. - * A DOM-representation of the incoming String will be created - * @param xmlResponse <code><InfoboxReadResponse></code> as String - * @throws MOASigServiceParserException on any parsing error - */ - public VerifyXMLSignatureResponseParser(String xmlResponse) throws MOASigServiceParserException { - try { - final InputStream s = new ByteArrayInputStream(xmlResponse.getBytes("UTF-8")); - verifyXMLSignatureResponse = DOMUtils.parseXmlValidating(s); - - } catch (final Throwable t) { - log.warn("Can not parse MOA-Sig response." , t); - throw new MOASigServiceParserException("service.moasig.02", new Object[] { t.toString() }, t); - - } - } - - /** - * Constructor for VerifyXMLSignatureResponseParser. - * A DOM-representation of the incoming Inputstream will be created - * @param xmlResponse <code><InfoboxReadResponse></code> as InputStream - * @throws MOASigServiceParserException on any parsing error - */ - public VerifyXMLSignatureResponseParser(InputStream xmlResponse) throws MOASigServiceParserException { - try { - verifyXMLSignatureResponse = DOMUtils.parseXmlValidating(xmlResponse); - - } catch (final Throwable t) { - log.warn("Can not parse MOA-Sig response." , t); - throw new MOASigServiceParserException("service.moasig.02", new Object[] { t.toString() }, t); - - } - } - - /** - * Constructor for VerifyXMLSignatureResponseParser. - * The incoming Element will be used for further operations - * @param xmlResponse <code><InfoboxReadResponse></code> as Element - */ - public VerifyXMLSignatureResponseParser(Element xmlResponse) { - verifyXMLSignatureResponse =xmlResponse; - - } - -/** - * Parse MOA-Sig signatur-verification result into {@link IXMLSignatureVerificationResponse} - * - * @return {@link IXMLSignatureVerificationResponse} - * @throws MOASigServiceException on any parsing error - */ - @NonNull - public IXMLSignatureVerificationResponse parseData() throws MOASigServiceException { - try { - final VerifyXMLSignatureResponse respData = new VerifyXMLSignatureResponse(); - respData.setXmlDsigSubjectName(XPathUtils.getElementValue(verifyXMLSignatureResponse,DSIG_SUBJECT_NAME_XPATH,"")); - final Element e = (Element)XPathUtils.selectSingleNode(verifyXMLSignatureResponse,QUALIFIED_CERTIFICATE_XPATH); - respData.setQualifiedCertificate(e!=null); - - final Base64InputStream in = new Base64InputStream(new ByteArrayInputStream(XPathUtils.getElementValue( - verifyXMLSignatureResponse,DSIG_X509_CERTIFICATE_XPATH,"").getBytes("UTF-8")),true); - - respData.setX509CertificateEncoded(new X509Certificate(in).getEncoded()); - - final Element publicAuthority = (Element)XPathUtils.selectSingleNode(verifyXMLSignatureResponse,PUBLIC_AUTHORITY_XPATH); - respData.setPublicAuthority(publicAuthority != null); - respData.setPublicAuthorityCode(XPathUtils.getElementValue(verifyXMLSignatureResponse,PUBLIC_AUTHORITY_CODE_XPATH,"")); - respData.setSignatureCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNATURE_CHECK_CODE_XPATH,"")).intValue()); - - final String xmlDsigCheckCode = XPathUtils.getElementValue(verifyXMLSignatureResponse,XMLDSIG_MANIFEST_CHECK_CODE_XPATH,null); - if (xmlDsigCheckCode!=null) { - respData.setXmlDSIGManigest(true); - respData.setXmlDSIGManifestCheckCode(new Integer(xmlDsigCheckCode).intValue()); - - } else { - respData.setXmlDSIGManigest(false); - - } - - final String signatureManifestCheckCode = XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNATURE_MANIFEST_CHECK_CODE_XPATH,null); - if (signatureManifestCheckCode != null) { - respData.setSignatureManifestCheckCode(new Integer(signatureManifestCheckCode).intValue()); - - } - respData.setCertificateCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,CERTIFICATE_CHECK_CODE_XPATH,"")).intValue()); - - final String signingTimeElement = XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNING_TIME_XPATH,""); - if (signingTimeElement != null && !signingTimeElement.isEmpty()) { - final DateTime datetime = ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(signingTimeElement); - respData.setSigningDateTime(datetime.toDate()); - - } - - return respData; - - } catch (final Throwable t) { - log.warn("Can not parse MOA-Sig response." , t); - throw new MOASigServiceParserException("service.moasig.02", new Object[] { t.toString() }, t); - } - - } - - -} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java new file mode 100644 index 00000000..8cf941a7 --- /dev/null +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eid/authhandler/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java @@ -0,0 +1,192 @@ +package at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.parser; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.api.data.IXMLSignatureVerificationResponse; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.exceptions.MoaSigServiceParserException; +import at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moaspss.util.Constants; +import at.gv.egovernment.moaspss.util.DOMUtils; +import at.gv.egovernment.moaspss.util.XPathUtils; +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.lang.NonNull; +import org.w3c.dom.Element; +import iaik.utils.Base64InputStream; +import iaik.x509.X509Certificate; + + +public class VerifyXmlSignatureResponseParser { + private static final Logger log = LoggerFactory.getLogger(VerifyXmlSignatureResponseParser.class); + + // + // XPath namespace prefix shortcuts + // + /** Xpath prefix for reaching MOA Namespaces. */ + private static final String MOA = Constants.MOA_PREFIX + ":"; + /** Xpath prefix for reaching DSIG Namespaces. */ + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + /** Xpath expression to the root element. */ + private static final String ROOT = "/" + MOA + "VerifyXMLSignatureResponse/"; + + /** Xpath expression to the X509SubjectName element. */ + private static final String DSIG_SUBJECT_NAME_XPATH = + ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + DSIG + "X509SubjectName"; + /** Xpath expression to the X509Certificate element. */ + private static final String DSIG_X509_CERTIFICATE_XPATH = + ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + DSIG + "X509Certificate"; + /** Xpath expression to the PublicAuthority element. */ + private static final String PUBLIC_AUTHORITY_XPATH = + ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + MOA + "PublicAuthority"; + /** Xpath expression to the PublicAuthorityCode element. */ + private static final String PUBLIC_AUTHORITY_CODE_XPATH = + PUBLIC_AUTHORITY_XPATH + "/" + MOA + "Code"; + /** Xpath expression to the QualifiedCertificate element. */ + private static final String QUALIFIED_CERTIFICATE_XPATH = + ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + MOA + "QualifiedCertificate"; + + /** Xpath expression to the SignatureCheckCode element. */ + private static final String SIGNATURE_CHECK_CODE_XPATH = + ROOT + MOA + "SignatureCheck/" + MOA + "Code"; + /** Xpath expression to the XMLDSIGManifestCheckCode element. */ + private static final String XMLDSIG_MANIFEST_CHECK_CODE_XPATH = + ROOT + MOA + "XMLDSIGManifestCheck/" + MOA + "Code"; + /** Xpath expression to the SignatureManifestCheckCode element. */ + private static final String SIGNATURE_MANIFEST_CHECK_CODE_XPATH = + ROOT + MOA + "SignatureManifestCheck/" + MOA + "Code"; + /** Xpath expression to the CertificateCheckCode element. */ + private static final String CERTIFICATE_CHECK_CODE_XPATH = + ROOT + MOA + "CertificateCheck/" + MOA + "Code"; + + private static final String SIGNING_TIME_XPATH = ROOT + MOA + "SigningTime"; + + + /** This is the root element of the XML-Document provided by the Security Layer Card. */ + private Element verifyXmlSignatureResponse; + + /** + * Constructor for VerifyXMLSignatureResponseParser. A DOM-representation of the incoming String + * will be created + * + * @param xmlResponse <code><InfoboxReadResponse></code> as String + * @throws MoaSigServiceParserException on any parsing error + */ + public VerifyXmlSignatureResponseParser(final String xmlResponse) + throws MoaSigServiceParserException { + try { + final InputStream s = new ByteArrayInputStream(xmlResponse.getBytes("UTF-8")); + verifyXmlSignatureResponse = DOMUtils.parseXmlValidating(s); + + } catch (final Throwable t) { + log.warn("Can not parse MOA-Sig response.", t); + throw new MoaSigServiceParserException("service.moasig.02", new Object[] {t.toString()}, t); + + } + } + + /** + * Constructor for VerifyXMLSignatureResponseParser. A DOM-representation of the incoming + * Inputstream will be created + * + * @param xmlResponse <code><InfoboxReadResponse></code> as InputStream + * @throws MoaSigServiceParserException on any parsing error + */ + public VerifyXmlSignatureResponseParser(final InputStream xmlResponse) + throws MoaSigServiceParserException { + try { + verifyXmlSignatureResponse = DOMUtils.parseXmlValidating(xmlResponse); + + } catch (final Throwable t) { + log.warn("Can not parse MOA-Sig response.", t); + throw new MoaSigServiceParserException("service.moasig.02", new Object[] {t.toString()}, t); + + } + } + + /** + * Constructor for VerifyXMLSignatureResponseParser. The incoming Element will be used for further + * operations + * + * @param xmlResponse <code><InfoboxReadResponse></code> as Element + */ + public VerifyXmlSignatureResponseParser(final Element xmlResponse) { + verifyXmlSignatureResponse = xmlResponse; + + } + + /** + * Parse MOA-Sig signatur-verification result into {@link IXMLSignatureVerificationResponse}. + * + * @return {@link IXMLSignatureVerificationResponse} + * @throws MoaSigServiceException on any parsing error + */ + @NonNull + public IXMLSignatureVerificationResponse parseData() throws MoaSigServiceException { + try { + final VerifyXMLSignatureResponse respData = new VerifyXMLSignatureResponse(); + respData.setXmlDsigSubjectName( + XPathUtils.getElementValue(verifyXmlSignatureResponse, DSIG_SUBJECT_NAME_XPATH, "")); + final Element e = (Element) XPathUtils.selectSingleNode(verifyXmlSignatureResponse, + QUALIFIED_CERTIFICATE_XPATH); + respData.setQualifiedCertificate(e != null); + + final Base64InputStream in = new Base64InputStream(new ByteArrayInputStream( + XPathUtils.getElementValue(verifyXmlSignatureResponse, DSIG_X509_CERTIFICATE_XPATH, "") + .getBytes("UTF-8")), + true); + + respData.setX509CertificateEncoded(new X509Certificate(in).getEncoded()); + + final Element publicAuthority = + (Element) XPathUtils.selectSingleNode(verifyXmlSignatureResponse, PUBLIC_AUTHORITY_XPATH); + respData.setPublicAuthority(publicAuthority != null); + respData.setPublicAuthorityCode( + XPathUtils.getElementValue(verifyXmlSignatureResponse, PUBLIC_AUTHORITY_CODE_XPATH, "")); + respData.setSignatureCheckCode(new Integer( + XPathUtils.getElementValue(verifyXmlSignatureResponse, SIGNATURE_CHECK_CODE_XPATH, "")) + .intValue()); + + final String xmlDsigCheckCode = XPathUtils.getElementValue(verifyXmlSignatureResponse, + XMLDSIG_MANIFEST_CHECK_CODE_XPATH, null); + if (xmlDsigCheckCode != null) { + respData.setXmlDSIGManigest(true); + respData.setXmlDSIGManifestCheckCode(new Integer(xmlDsigCheckCode).intValue()); + + } else { + respData.setXmlDSIGManigest(false); + + } + + final String signatureManifestCheckCode = XPathUtils + .getElementValue(verifyXmlSignatureResponse, SIGNATURE_MANIFEST_CHECK_CODE_XPATH, null); + if (signatureManifestCheckCode != null) { + respData.setSignatureManifestCheckCode(new Integer(signatureManifestCheckCode).intValue()); + + } + respData.setCertificateCheckCode(new Integer( + XPathUtils.getElementValue(verifyXmlSignatureResponse, CERTIFICATE_CHECK_CODE_XPATH, "")) + .intValue()); + + final String signingTimeElement = + XPathUtils.getElementValue(verifyXmlSignatureResponse, SIGNING_TIME_XPATH, ""); + if (signingTimeElement != null && !signingTimeElement.isEmpty()) { + final DateTime datetime = + ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(signingTimeElement); + respData.setSigningDateTime(datetime.toDate()); + + } + + return respData; + + } catch (final Throwable t) { + log.warn("Can not parse MOA-Sig response.", t); + throw new MoaSigServiceParserException("service.moasig.02", new Object[] {t.toString()}, t); + } + + } + + +} diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/resources/moa-sig-service.beans.xml b/eaaf_modules/eaaf_module_moa-sig/src/main/resources/moa-sig-service.beans.xml index 60b75f3c..c5e05853 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/main/resources/moa-sig-service.beans.xml +++ b/eaaf_modules/eaaf_module_moa-sig/src/main/resources/moa-sig-service.beans.xml @@ -1,25 +1,25 @@ <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xmlns:tx="http://www.springframework.org/schema/tx" - xmlns:aop="http://www.springframework.org/schema/aop" - xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd - http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> - <context:annotation-config /> + <context:annotation-config /> + + <bean id="moaSigInitializer" + class="at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.MoaSigInitializer" /> + + <bean id="moaSigVerifyService" + class="at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.SignatureVerificationService" + depends-on="moaSigInitializer" /> + + <bean id="moaSigCreateService" + class="at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.SignatureCreationService" + depends-on="moaSigInitializer" /> - <bean id="moaSigInitializer" - class="at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.MoaSigInitializer" /> - - <bean id="moaSigVerifyService" - class="at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.SignatureVerificationService" - depends-on="moaSigInitializer" /> - - <bean id="moaSigCreateService" - class="at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.SignatureCreationService" - depends-on="moaSigInitializer" /> - </beans>
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_moa-sig/src/test/java/artifacts/MavenArtifactInstaller.java b/eaaf_modules/eaaf_module_moa-sig/src/test/java/artifacts/MavenArtifactInstaller.java index 7b9e2748..11c84ec0 100644 --- a/eaaf_modules/eaaf_module_moa-sig/src/test/java/artifacts/MavenArtifactInstaller.java +++ b/eaaf_modules/eaaf_module_moa-sig/src/test/java/artifacts/MavenArtifactInstaller.java @@ -6,54 +6,65 @@ import java.text.MessageFormat; public class MavenArtifactInstaller { - public static final String MVN_INSTALL_PATH = "F:\\local_work\\program\\apache-maven-3.5.2-bin\\bin\\"; - public static final String CONFIG = "/settings.xml"; - public static final String REPO_SCAN_PATH = "/repository/iaik/prod"; - - public static final String GROUP = "iaik.prod"; - public static final String PACKAGE = "jar"; - public static final String COMMAND_TEMPLATE = "{6}mvn.cmd install:install-file -s {0} -DgroupId={1} -DartifactId={2} -Dversion={3} -Dpackaging={4} -Dfile={5}"; - - public static void main(String[] args) { - String currentLocation = new java.io.File( "." ).toURI().toString(); - currentLocation = currentLocation.substring("file:/".length(), currentLocation.length() - 2); - final String settingLocation = currentLocation + CONFIG; - final File settingsFile = new File(settingLocation); - if (!settingsFile.exists()) { - System.out.println("Maven settings does not exist"); - System.exit(-1); - - } - - final String pathToScan = currentLocation + REPO_SCAN_PATH; - - final File toScan = new File(pathToScan); - - int counter=0; - for (final File dir : toScan.listFiles()) { - final String artifactName = dir.getName(); - for (final File version : dir.listFiles()) { - final String libVersion = version.getName(); - final String jarPath = version.getAbsolutePath() + "/" + artifactName + "-" + libVersion + ".jar"; - final File jar = new File(jarPath ); - if (jar.exists()) { - final String mvnCommand = MessageFormat.format(COMMAND_TEMPLATE, settingsFile.getAbsoluteFile(), GROUP, artifactName, libVersion, PACKAGE, jar.getAbsolutePath(), MVN_INSTALL_PATH); - System.out.println("Execute: " + mvnCommand); - try { - Runtime.getRuntime().exec(mvnCommand); - counter++; - } catch (final IOException e) { - e.printStackTrace(); - - } - - } else - System.out.print("Can NOT find jar with path: " + jarPath); - - } - - } - System.out.println("Install #" + counter + " maven artifacts"); - } + public static final String MVN_INSTALL_PATH = + "F:\\local_work\\program\\apache-maven-3.5.2-bin\\bin\\"; + public static final String CONFIG = "/settings.xml"; + public static final String REPO_SCAN_PATH = "/repository/iaik/prod"; + + public static final String GROUP = "iaik.prod"; + public static final String PACKAGE = "jar"; + public static final String COMMAND_TEMPLATE = + "{6}mvn.cmd install:install-file -s {0} -DgroupId={1} -DartifactId={2} -Dversion={3} -Dpackaging={4} -Dfile={5}"; + + /** + * Only for test-deployment of maven artifacts. + * + * @param args System parameters + */ + public static void main(final String[] args) { + String currentLocation = new java.io.File(".").toURI().toString(); + currentLocation = currentLocation.substring("file:/".length(), currentLocation.length() - 2); + final String settingLocation = currentLocation + CONFIG; + final File settingsFile = new File(settingLocation); + if (!settingsFile.exists()) { + System.out.println("Maven settings does not exist"); + System.exit(-1); + + } + + final String pathToScan = currentLocation + REPO_SCAN_PATH; + + final File toScan = new File(pathToScan); + + int counter = 0; + for (final File dir : toScan.listFiles()) { + final String artifactName = dir.getName(); + for (final File version : dir.listFiles()) { + final String libVersion = version.getName(); + final String jarPath = + version.getAbsolutePath() + "/" + artifactName + "-" + libVersion + ".jar"; + final File jar = new File(jarPath); + if (jar.exists()) { + final String mvnCommand = + MessageFormat.format(COMMAND_TEMPLATE, settingsFile.getAbsoluteFile(), GROUP, + artifactName, libVersion, PACKAGE, jar.getAbsolutePath(), MVN_INSTALL_PATH); + System.out.println("Execute: " + mvnCommand); + try { + Runtime.getRuntime().exec(mvnCommand); + counter++; + } catch (final IOException e) { + e.printStackTrace(); + + } + + } else { + System.out.print("Can NOT find jar with path: " + jarPath); + } + + } + + } + System.out.println("Install #" + counter + " maven artifacts"); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVP2SProfileCoreSpringResourceProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVP2SProfileCoreSpringResourceProvider.java deleted file mode 100644 index c72db697..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVP2SProfileCoreSpringResourceProvider.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import at.gv.egiz.components.spring.api.SpringResourceProvider; - -public class PVP2SProfileCoreSpringResourceProvider implements SpringResourceProvider { - - @Override - public String getName() { - return "EAAF PVP2 S-Profile Core SpringResourceProvider"; - } - - @Override - public String[] getPackagesToScan() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource[] getResourcesToLoad() { - ClassPathResource sl20AuthConfig = new ClassPathResource("/eaaf_pvp.beans.xml", PVP2SProfileCoreSpringResourceProvider.class); - - return new Resource[] {sl20AuthConfig}; - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVPConstants.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVPConstants.java deleted file mode 100644 index 3b57a7e3..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVPConstants.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.opensaml.xml.encryption.EncryptionConstants; -import org.opensaml.xml.signature.SignatureConstants; - -import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; -import at.gv.egiz.eaaf.core.impl.data.Trible; - -public interface PVPConstants extends PVPAttributeDefinitions { - - public static final String DEFAULT_SIGNING_METHODE = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256; - public static final String DEFAULT_DIGESTMETHODE = SignatureConstants.ALGO_ID_DIGEST_SHA256; - public static final String DEFAULT_SYM_ENCRYPTION_METHODE = EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256; - public static final String DEFAULT_ASYM_ENCRYPTION_METHODE = EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP; - - public static final String ENTITY_CATEGORY_ATTRIBITE = "http://macedir.org/entity-category"; - public static final String EGOVTOKEN = "http://www.ref.gv.at/ns/names/agiz/pvp/egovtoken"; - public static final String CITIZENTOKEN = "http://www.ref.gv.at/ns/names/agiz/pvp/citizentoken"; - - @Deprecated - public static final String STORK_ATTRIBUTE_PREFIX = "http://www.stork.gov.eu/"; - - public static final String REDIRECT = "Redirect"; - public static final String POST = "Post"; - public static final String SOAP = "Soap"; - public static final String METADATA = "Metadata"; - public static final String ATTRIBUTEQUERY = "AttributeQuery"; - public static final String SINGLELOGOUT = "SingleLogOut"; - - /** - * - * Get required PVP attributes for egovtoken - * First : PVP attribute name (OID) - * Second: FriendlyName - * Third: Required - * - */ - public static final List<Trible<String, String, Boolean>> EGOVTOKEN_PVP_ATTRIBUTES = - Collections.unmodifiableList(new ArrayList<Trible<String, String, Boolean>>() { - private static final long serialVersionUID = 1L; - { - //currently supported attributes - add(Trible.newInstance(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, true)); - add(Trible.newInstance(PRINCIPAL_NAME_NAME, PRINCIPAL_NAME_FRIENDLY_NAME, true)); - - //currently not supported attributes - add(Trible.newInstance(USERID_NAME, USERID_FRIENDLY_NAME, false)); - add(Trible.newInstance(GID_NAME, GID_FRIENDLY_NAME, false)); - add(Trible.newInstance(PARTICIPANT_ID_NAME, PARTICIPANT_ID_FRIENDLY_NAME, false)); - add(Trible.newInstance(OU_GV_OU_ID_NAME, OU_GV_OU_ID_FRIENDLY_NAME, false)); - add(Trible.newInstance(OU_NAME, OU_FRIENDLY_NAME, false)); - add(Trible.newInstance(SECCLASS_NAME, SECCLASS_FRIENDLY_NAME, false)); - - - } - }); - - /** - * - * Get required PVP attributes for citizenToken - * First : PVP attribute name (OID) - * Second: FriendlyName - * Third: Required - * - */ - public static final List<Trible<String, String, Boolean>> CITIZENTOKEN_PVP_ATTRIBUTES = - Collections.unmodifiableList(new ArrayList<Trible<String, String, Boolean>>() { - private static final long serialVersionUID = 1L; - { - //required attributes - eIDAS minimal-data set - add(Trible.newInstance(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, true)); - add(Trible.newInstance(PRINCIPAL_NAME_NAME, PRINCIPAL_NAME_FRIENDLY_NAME, true)); - add(Trible.newInstance(GIVEN_NAME_NAME, GIVEN_NAME_FRIENDLY_NAME, true)); - add(Trible.newInstance(BIRTHDATE_NAME, BIRTHDATE_FRIENDLY_NAME, true)); - add(Trible.newInstance(BPK_NAME, BPK_FRIENDLY_NAME, true)); - - - //not required attributes - add(Trible.newInstance(EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, false)); - add(Trible.newInstance(EID_ISSUING_NATION_NAME, EID_ISSUING_NATION_FRIENDLY_NAME, false)); - add(Trible.newInstance(EID_SECTOR_FOR_IDENTIFIER_NAME, EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_TYPE_NAME, MANDATE_TYPE_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_TYPE_OID_NAME, MANDATE_TYPE_OID_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_LEG_PER_SOURCE_PIN_NAME, MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_NAT_PER_BPK_NAME, MANDATE_NAT_PER_BPK_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_NAT_PER_GIVEN_NAME_NAME, MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_NAT_PER_FAMILY_NAME_NAME, MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_NAT_PER_BIRTHDATE_NAME, MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_LEG_PER_FULL_NAME_NAME, MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_PROF_REP_OID_NAME, MANDATE_PROF_REP_OID_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_PROF_REP_DESC_NAME, MANDATE_PROF_REP_DESC_FRIENDLY_NAME, false)); - add(Trible.newInstance(MANDATE_REFERENCE_VALUE_NAME, MANDATE_REFERENCE_VALUE_FRIENDLY_NAME, false)); - - - - } - }); - - //constants for requested SAML2 attribtes by using own namespace - public static final String EIDAT10_SAML_NS = "http://eid.gv.at/eID/attributes/saml-extensions"; - public static final String EIDAT10_PREFIX = "eid"; - - public static final QName EIDAS_REQUESTED_ATTRIBUTE_VALUE_TYPE = - new QName(EIDAT10_SAML_NS, "AttributeValue", EIDAT10_PREFIX); - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVPEventConstants.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVPEventConstants.java deleted file mode 100644 index d1f619bf..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PVPEventConstants.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2; - -public class PVPEventConstants { - - //TODO!!! - public static final int AUTHPROTOCOL_PVP_METADATA = 3100; - public static final int AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST = 3101; - public static final int AUTHPROTOCOL_PVP_RESPONSE_ASSERTION = 3105; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/Pvp2SProfileCoreSpringResourceProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/Pvp2SProfileCoreSpringResourceProvider.java new file mode 100644 index 00000000..c0482c9d --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/Pvp2SProfileCoreSpringResourceProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class Pvp2SProfileCoreSpringResourceProvider implements SpringResourceProvider { + + @Override + public String getName() { + return "EAAF PVP2 S-Profile Core SpringResourceProvider"; + } + + @Override + public String[] getPackagesToScan() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource[] getResourcesToLoad() { + final ClassPathResource sl20AuthConfig = + new ClassPathResource("/eaaf_pvp.beans.xml", Pvp2SProfileCoreSpringResourceProvider.class); + + return new Resource[] {sl20AuthConfig}; + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PvpConstants.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PvpConstants.java new file mode 100644 index 00000000..e8d42e80 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PvpConstants.java @@ -0,0 +1,138 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; +import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import org.opensaml.xml.encryption.EncryptionConstants; +import org.opensaml.xml.signature.SignatureConstants; + +public interface PvpConstants extends PVPAttributeDefinitions { + + public static final String DEFAULT_SIGNING_METHODE = + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256; + public static final String DEFAULT_DIGESTMETHODE = SignatureConstants.ALGO_ID_DIGEST_SHA256; + public static final String DEFAULT_SYM_ENCRYPTION_METHODE = + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256; + public static final String DEFAULT_ASYM_ENCRYPTION_METHODE = + EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP; + + public static final String ENTITY_CATEGORY_ATTRIBITE = "http://macedir.org/entity-category"; + public static final String EGOVTOKEN = "http://www.ref.gv.at/ns/names/agiz/pvp/egovtoken"; + public static final String CITIZENTOKEN = "http://www.ref.gv.at/ns/names/agiz/pvp/citizentoken"; + + @Deprecated + public static final String STORK_ATTRIBUTE_PREFIX = "http://www.stork.gov.eu/"; + + public static final String REDIRECT = "Redirect"; + public static final String POST = "Post"; + public static final String SOAP = "Soap"; + public static final String METADATA = "Metadata"; + public static final String ATTRIBUTEQUERY = "AttributeQuery"; + public static final String SINGLELOGOUT = "SingleLogOut"; + + /** + * Get required PVP attributes for egovtoken First : PVP attribute name (OID) Second: FriendlyName + * Third: Required. + * + */ + public static final List<Trible<String, String, Boolean>> EGOVTOKEN_PVP_ATTRIBUTES = + Collections.unmodifiableList(new ArrayList<Trible<String, String, Boolean>>() { + private static final long serialVersionUID = 1L; + { + // currently supported attributes + add(Trible.newInstance(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, true)); + add(Trible.newInstance(PRINCIPAL_NAME_NAME, PRINCIPAL_NAME_FRIENDLY_NAME, true)); + + // currently not supported attributes + add(Trible.newInstance(USERID_NAME, USERID_FRIENDLY_NAME, false)); + add(Trible.newInstance(GID_NAME, GID_FRIENDLY_NAME, false)); + add(Trible.newInstance(PARTICIPANT_ID_NAME, PARTICIPANT_ID_FRIENDLY_NAME, false)); + add(Trible.newInstance(OU_GV_OU_ID_NAME, OU_GV_OU_ID_FRIENDLY_NAME, false)); + add(Trible.newInstance(OU_NAME, OU_FRIENDLY_NAME, false)); + add(Trible.newInstance(SECCLASS_NAME, SECCLASS_FRIENDLY_NAME, false)); + + + } + }); + + /** + * Get required PVP attributes for citizenToken First : PVP attribute name (OID) Second: + * FriendlyName Third: Required. + * + */ + public static final List<Trible<String, String, Boolean>> CITIZENTOKEN_PVP_ATTRIBUTES = + Collections.unmodifiableList(new ArrayList<Trible<String, String, Boolean>>() { + private static final long serialVersionUID = 1L; + { + // required attributes - eIDAS minimal-data set + add(Trible.newInstance(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, true)); + add(Trible.newInstance(PRINCIPAL_NAME_NAME, PRINCIPAL_NAME_FRIENDLY_NAME, true)); + add(Trible.newInstance(GIVEN_NAME_NAME, GIVEN_NAME_FRIENDLY_NAME, true)); + add(Trible.newInstance(BIRTHDATE_NAME, BIRTHDATE_FRIENDLY_NAME, true)); + add(Trible.newInstance(BPK_NAME, BPK_FRIENDLY_NAME, true)); + + + // not required attributes + add(Trible.newInstance(EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, + EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, false)); + add(Trible.newInstance(EID_ISSUING_NATION_NAME, EID_ISSUING_NATION_FRIENDLY_NAME, false)); + add(Trible.newInstance(EID_SECTOR_FOR_IDENTIFIER_NAME, + EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_TYPE_NAME, MANDATE_TYPE_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_TYPE_OID_NAME, MANDATE_TYPE_OID_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_LEG_PER_SOURCE_PIN_NAME, + MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, + MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_NAT_PER_BPK_NAME, MANDATE_NAT_PER_BPK_FRIENDLY_NAME, + false)); + add(Trible.newInstance(MANDATE_NAT_PER_GIVEN_NAME_NAME, + MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_NAT_PER_FAMILY_NAME_NAME, + MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_NAT_PER_BIRTHDATE_NAME, + MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_LEG_PER_FULL_NAME_NAME, + MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME, false)); + add(Trible.newInstance(MANDATE_PROF_REP_OID_NAME, MANDATE_PROF_REP_OID_FRIENDLY_NAME, + false)); + add(Trible.newInstance(MANDATE_PROF_REP_DESC_NAME, MANDATE_PROF_REP_DESC_FRIENDLY_NAME, + false)); + add(Trible.newInstance(MANDATE_REFERENCE_VALUE_NAME, + MANDATE_REFERENCE_VALUE_FRIENDLY_NAME, false)); + + + + } + }); + + // constants for requested SAML2 attribtes by using own namespace + public static final String EIDAT10_SAML_NS = "http://eid.gv.at/eID/attributes/saml-extensions"; + public static final String EIDAT10_PREFIX = "eid"; + + public static final QName EIDAS_REQUESTED_ATTRIBUTE_VALUE_TYPE = + new QName(EIDAT10_SAML_NS, "AttributeValue", EIDAT10_PREFIX); + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PvpEventConstants.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PvpEventConstants.java new file mode 100644 index 00000000..41b64470 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/PvpEventConstants.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2; + +public class PvpEventConstants { + + // TODO!!! + public static final int AUTHPROTOCOL_PVP_METADATA = 3100; + public static final int AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST = 3101; + public static final int AUTHPROTOCOL_PVP_RESPONSE_ASSERTION = 3105; + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/IPVP2BasicConfiguration.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/IPVP2BasicConfiguration.java deleted file mode 100644 index 48b0efc5..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/IPVP2BasicConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api; - -import java.util.List; - -import org.opensaml.saml2.metadata.ContactPerson; -import org.opensaml.saml2.metadata.Organization; - -import at.gv.egiz.eaaf.core.exceptions.EAAFException; - -public interface IPVP2BasicConfiguration { - - public String getIDPEntityId(String authURL) throws EAAFException; - - public String getIDPSSOPostService(String authURL) throws EAAFException; - - public String getIDPSSORedirectService(String authURL) throws EAAFException; - - public Object getIDPSSOSOAPService(String extractAuthURLFromRequest) throws EAAFException; - - public List<ContactPerson> getIDPContacts() throws EAAFException; - - public Organization getIDPOrganisation() throws EAAFException; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/IPvo2BasicConfiguration.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/IPvo2BasicConfiguration.java new file mode 100644 index 00000000..39c0baff --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/IPvo2BasicConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api; + +import java.util.List; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.Organization; + +public interface IPvo2BasicConfiguration { + + String getIdpEntityId(String authUrl) throws EaafException; + + String getIdpSsoPostService(String authUrl) throws EaafException; + + String getIdpSsoRedirectService(String authUrl) throws EaafException; + + Object getIspSsoSoapService(String extractAuthUrlFromRequest) throws EaafException; + + List<ContactPerson> getIdpContacts() throws EaafException; + + Organization getIdpOrganisation() throws EaafException; + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IDecoder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IDecoder.java index 3b264b6d..27a6532b 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IDecoder.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IDecoder.java @@ -1,49 +1,40 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.api.binding; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.common.binding.decoding.URIComparator; import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.xml.security.SecurityException; -import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; - public interface IDecoder { - public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) - throws MessageDecodingException, SecurityException, PVP2Exception; - - public boolean handleDecode(String action, HttpServletRequest req); - - public String getSAML2BindingName(); + public InboundMessageInterface decode(HttpServletRequest req, HttpServletResponse resp, + MetadataProvider metadataProvider, boolean isSpEndPoint, URIComparator comparator) + throws MessageDecodingException, SecurityException, Pvp2Exception; + + public boolean handleDecode(String action, HttpServletRequest req); + + public String getSaml2BindingName(); } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IEncoder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IEncoder.java index ec400e7a..9d8b0105 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IEncoder.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/binding/IEncoder.java @@ -1,75 +1,70 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.api.binding; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.StatusResponseType; import org.opensaml.ws.message.encoder.MessageEncodingException; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.credential.Credential; -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; - public interface IEncoder { - - /** - * - * @param req The http request - * @param resp The http response - * @param request The SAML2 request object - * @param targetLocation URL, where the request should be transmit - * @param relayState token for session handling - * @param credentials Credential to sign the request object - * @param pendingReq Internal MOA-ID request object that contains session-state informations but never null - * @throws MessageEncodingException - * @throws SecurityException - * @throws PVP2Exception - */ - public void encodeRequest(HttpServletRequest req, - HttpServletResponse resp, RequestAbstractType request, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) - throws MessageEncodingException, SecurityException, PVP2Exception; - - /** - * Encoder SAML Response - * @param req The http request - * @param resp The http response - * @param response The SAML2 repsonse object - * @param targetLocation URL, where the request should be transmit - * @param relayState token for session handling - * @param credentials Credential to sign the response object - * @param pendingReq Internal MOA-ID request object that contains session-state informations but never null - * @throws MessageEncodingException - * @throws SecurityException - */ - public void encodeRespone(HttpServletRequest req, - HttpServletResponse resp, StatusResponseType response, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) - throws MessageEncodingException, SecurityException, PVP2Exception; + + /** + * SAML2 Request encoder. + * + * @param req The http request + * @param resp The http response + * @param request The SAML2 request object + * @param targetLocation URL, where the request should be transmit + * @param relayState token for session handling + * @param credentials Credential to sign the request object + * @param pendingReq Internal MOA-ID request object that contains session-state informations but + * never null + * @throws MessageEncodingException In case of an error + * @throws SecurityException In case of an error + * @throws Pvp2Exception In case of an error + */ + void encodeRequest(HttpServletRequest req, HttpServletResponse resp, + RequestAbstractType request, String targetLocation, String relayState, Credential credentials, + IRequest pendingReq) throws MessageEncodingException, SecurityException, Pvp2Exception; + + /** + * Encoder SAML Response. + * + * @param req The http request + * @param resp The http response + * @param response The SAML2 repsonse object + * @param targetLocation URL, where the request should be transmit + * @param relayState token for session handling + * @param credentials Credential to sign the response object + * @param pendingReq Internal MOA-ID request object that contains session-state informations but + * never null + * @throws MessageEncodingException In case of an error + * @throws SecurityException In case of an error + */ + void encodeRespone(HttpServletRequest req, HttpServletResponse resp, + StatusResponseType response, String targetLocation, String relayState, Credential credentials, + IRequest pendingReq) throws MessageEncodingException, SecurityException, Pvp2Exception; } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/message/InboundMessageInterface.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/message/InboundMessageInterface.java index 416672a1..e5b253a2 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/message/InboundMessageInterface.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/message/InboundMessageInterface.java @@ -1,42 +1,34 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.api.message; import org.w3c.dom.Element; -/** - * @author tlenz - * - */ public interface InboundMessageInterface { - - public String getRelayState(); - public String getEntityID(); - public boolean isVerified(); - public Element getInboundMessage(); - + + String getRelayState(); + + String getEntityID(); + + boolean isVerified(); + + Element getInboundMessage(); + } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataBuilderConfiguration.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataBuilderConfiguration.java deleted file mode 100644 index c041ec72..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataBuilderConfiguration.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api.metadata; - -import java.util.Collection; -import java.util.List; - -import org.opensaml.saml2.core.Attribute; -import org.opensaml.saml2.metadata.ContactPerson; -import org.opensaml.saml2.metadata.Organization; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.opensaml.xml.security.credential.Credential; - -import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; - -/** - * @author tlenz - * - */ -public interface IPVPMetadataBuilderConfiguration { - - - /** - * Defines a unique name for this PVP Service-provider, which is used for logging - * - * @return - */ - public String getSPNameForLogging(); - - /** - * Set metadata valid area - * - * @return valid until in hours [h] - */ - public int getMetadataValidUntil(); - - /** - * Build a SAML2 Entities element as metadata root element - * - * @return true, if the metadata should start with entities element - */ - public boolean buildEntitiesDescriptorAsRootElement(); - - /** - * - * - * @return true, if an IDP SSO-descriptor element should be generated - */ - public boolean buildIDPSSODescriptor(); - - /** - * - * - * @return true, if an SP SSO-descriptor element should be generated - */ - public boolean buildSPSSODescriptor(); - - /** - * Set the PVP entityID for this SAML2 metadata. - * The entityID must be an URL and must be start with the public-URL prefix of the server - * - * @return PVP entityID postfix as String - */ - public String getEntityID(); - - /** - * Set a friendlyName for this PVP entity - * - * @return - */ - public String getEntityFriendlyName(); - - /** - * Set the contact information for this metadata entity - * - * @return - */ - public List<ContactPerson> getContactPersonInformation(); - - /** - * Set organisation information for this metadata entity - * - * @return - */ - public Organization getOrgansiationInformation(); - - - /** - * Set the credential for metadata signing - * - * @return - * @throws CredentialsNotAvailableException - */ - public Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException; - - /** - * Set the credential for request/response signing - * IDP metadata: this credential is used for SAML2 response signing - * SP metadata: this credential is used for SAML2 response signing - * - * @return - * @throws CredentialsNotAvailableException - */ - public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException; - - /** - * Set the credential for response encryption - * - * @return - * @throws CredentialsNotAvailableException - */ - public Credential getEncryptionCredentials() throws CredentialsNotAvailableException; - - /** - * Set the IDP Post-Binding URL for WebSSO - * - * @return - */ - public String getIDPWebSSOPostBindingURL(); - - /** - * Set the IDP Redirect-Binding URL for WebSSO - * - * @return - */ - public String getIDPWebSSORedirectBindingURL(); - - /** - * Set the IDP Post-Binding URL for Single LogOut - * - * @return - */ - public String getIDPSLOPostBindingURL(); - - /** - * Set the IDP Redirect-Binding URL for Single LogOut - * - * @return - */ - public String getIDPSLORedirectBindingURL(); - - /** - * Set the SP Post-Binding URL for for the Assertion-Consumer Service - * - * @return - */ - public String getSPAssertionConsumerServicePostBindingURL(); - - /** - * Set the SP Redirect-Binding URL for the Assertion-Consumer Service - * - * @return - */ - public String getSPAssertionConsumerServiceRedirectBindingURL(); - - /** - * Set the SP Post-Binding URL for Single LogOut - * - * @return - */ - public String getSPSLOPostBindingURL(); - - /** - * Set the SP Redirect-Binding URL for Single LogOut - * - * @return - */ - public String getSPSLORedirectBindingURL(); - - /** - * Set the SP SOAP-Binding URL for Single LogOut - * - * @return - */ - public String getSPSLOSOAPBindingURL(); - - - /** - * Set all SAML2 attributes which could be provided by this IDP - * - * @return - */ - public List<Attribute> getIDPPossibleAttributes(); - - /** - * Set all nameID types which could be provided by this IDP - * - * @return a List of SAML2 nameID types - */ - public List<String> getIDPPossibleNameITTypes(); - - /** - * Set all SAML2 attributes which are required by the SP - * - * @return - */ - public Collection<RequestedAttribute> getSPRequiredAttributes(); - - /** - * Set all nameID types which allowed from the SP - * - * @return a List of SAML2 nameID types - */ - public List<String> getSPAllowedNameITTypes(); - - /** - * Set the 'wantAssertionSigned' attribute in SP metadata - * - * @return - */ - public boolean wantAssertionSigned(); - - /** - * Set the 'wantAuthnRequestSigned' attribute - * - * @return - */ - public boolean wantAuthnRequestSigned(); -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataConfigurationFactory.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataConfigurationFactory.java deleted file mode 100644 index be36a878..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataConfigurationFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api.metadata; - -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; - -public interface IPVPMetadataConfigurationFactory { - - public IPVPMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authURL, AbstractCredentialProvider pvpIDPCredentials); - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataProvider.java deleted file mode 100644 index f5c6a35a..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPVPMetadataProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api.metadata; - -import java.util.List; - -import javax.xml.namespace.QName; - -import org.opensaml.saml2.metadata.EntitiesDescriptor; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.RoleDescriptor; -import org.opensaml.saml2.metadata.provider.MetadataFilter; -import org.opensaml.saml2.metadata.provider.MetadataProvider; -import org.opensaml.saml2.metadata.provider.MetadataProviderException; -import org.opensaml.xml.XMLObject; - -public interface IPVPMetadataProvider extends MetadataProvider { - - boolean requireValidMetadata(); - - void setRequireValidMetadata(boolean requireValidMetadata); - - MetadataFilter getMetadataFilter(); - - void setMetadataFilter(MetadataFilter newFilter) throws MetadataProviderException; - - XMLObject getMetadata() throws MetadataProviderException; - - EntitiesDescriptor getEntitiesDescriptor(String entitiesID) throws MetadataProviderException; - - EntityDescriptor getEntityDescriptor(String entityID) throws MetadataProviderException; - - List<RoleDescriptor> getRole(String entityID, QName roleName) throws MetadataProviderException; - - RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol) throws MetadataProviderException; - -}
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataBuilderConfiguration.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataBuilderConfiguration.java new file mode 100644 index 00000000..f06a1684 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataBuilderConfiguration.java @@ -0,0 +1,236 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api.metadata; + +import java.util.Collection; +import java.util.List; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.Organization; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.xml.security.credential.Credential; + +/** + * PVP Metadata builder configuration. + * + * @author tlenz + * + */ +public interface IPvpMetadataBuilderConfiguration { + + + /** + * Defines a unique name for this PVP Service-provider, which is used for logging. + * + * @return + */ + String getSpNameForLogging(); + + /** + * Set metadata valid area. + * + * @return valid until in hours [h] + */ + int getMetadataValidUntil(); + + /** + * Build a SAML2 Entities element as metadata root element. + * + * @return true, if the metadata should start with entities element + */ + boolean buildEntitiesDescriptorAsRootElement(); + + /** + * Build an IDP SSO Descriptor. + * + * @return true, if an IDP SSO-descriptor element should be generated + */ + boolean buildIdpSsoDescriptor(); + + /** + * Build a SP Descriptor. + * + * @return true, if an SP SSO-descriptor element should be generated + */ + boolean buildSpSsoDescriptor(); + + /** + * Set the PVP entityID for this SAML2 metadata. The entityID must be an URL and must be start + * with the public-URL prefix of the server. + * + * @return PVP entityID postfix as String + */ + String getEntityID(); + + /** + * Set a friendlyName for this PVP entity. + * + * @return + */ + String getEntityFriendlyName(); + + /** + * Set the contact information for this metadata entity. + * + * @return + */ + List<ContactPerson> getContactPersonInformation(); + + /** + * Set organisation information for this metadata entity. + * + * @return + */ + Organization getOrgansiationInformation(); + + + /** + * Set the credential for metadata signing. + * + * @return Credentials + * @throws CredentialsNotAvailableException In case of an error + */ + Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException; + + /** + * Set the credential for request/response signing IDP metadata: this credential is used for SAML2 + * response signing SP metadata: this credential is used for SAML2 response signing. + * + * @return Credentials + * @throws CredentialsNotAvailableException In case of an error + */ + Credential getRequestorResponseSigningCredentials() + throws CredentialsNotAvailableException; + + /** + * Set the credential for response encryption. + * + * @return Credentials + * @throws CredentialsNotAvailableException In case of an error + */ + Credential getEncryptionCredentials() throws CredentialsNotAvailableException; + + /** + * Set the IDP Post-Binding URL for WebSSO. + * + * @return + */ + String getIdpWebSsoPostBindingUrl(); + + /** + * Set the IDP Redirect-Binding URL for WebSSO. + * + * @return + */ + String getIdpWebSsoRedirectBindingUrl(); + + /** + * Set the IDP Post-Binding URL for Single LogOut. + * + * @return + */ + String getIdpSloPostBindingUrl(); + + /** + * Set the IDP Redirect-Binding URL for Single LogOut. + * + * @return + */ + String getIdpSloRedirectBindingUrl(); + + /** + * Set the SP Post-Binding URL for for the Assertion-Consumer Service. + * + * @return + */ + String getSpAssertionConsumerServicePostBindingUrl(); + + /** + * Set the SP Redirect-Binding URL for the Assertion-Consumer Service. + * + * @return + */ + String getSpAssertionConsumerServiceRedirectBindingUrl(); + + /** + * Set the SP Post-Binding URL for Single LogOut. + * + * @return + */ + String getSpSloPostBindingUrl(); + + /** + * Set the SP Redirect-Binding URL for Single LogOut. + * + * @return + */ + String getSpSloRedirectBindingUrl(); + + /** + * Set the SP SOAP-Binding URL for Single LogOut. + * + * @return + */ + String getSpSloSoapBindingUrl(); + + + /** + * Set all SAML2 attributes which could be provided by this IDP. + * + * @return + */ + List<Attribute> getIdpPossibleAttributes(); + + /** + * Set all nameID types which could be provided by this IDP. + * + * @return a List of SAML2 nameID types + */ + List<String> getIdpPossibleNameIdTypes(); + + /** + * Set all SAML2 attributes which are required by the SP. + * + * @return + */ + Collection<RequestedAttribute> getSpRequiredAttributes(); + + /** + * Set all nameID types which allowed from the SP. + * + * @return a List of SAML2 nameID types + */ + List<String> getSpAllowedNameIdTypes(); + + /** + * Set the 'wantAssertionSigned' attribute in SP metadata. + * + * @return + */ + boolean wantAssertionSigned(); + + /** + * Set the 'wantAuthnRequestSigned' attribute. + * + * @return + */ + boolean wantAuthnRequestSigned(); +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataConfigurationFactory.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataConfigurationFactory.java new file mode 100644 index 00000000..4207d860 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataConfigurationFactory.java @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api.metadata; + +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; + +public interface IPvpMetadataConfigurationFactory { + + + IPvpMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authUrl, + AbstractCredentialProvider pvpIdpCredentials); + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataProvider.java new file mode 100644 index 00000000..bc90ff3f --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IPvpMetadataProvider.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api.metadata; + +import java.util.List; + +import javax.xml.namespace.QName; + +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.RoleDescriptor; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataProviderException; +import org.opensaml.xml.XMLObject; + +public interface IPvpMetadataProvider extends MetadataProvider { + + @Override + boolean requireValidMetadata(); + + @Override + void setRequireValidMetadata(boolean requireValidMetadata); + + @Override + MetadataFilter getMetadataFilter(); + + @Override + void setMetadataFilter(MetadataFilter newFilter) throws MetadataProviderException; + + @Override + XMLObject getMetadata() throws MetadataProviderException; + + @Override + EntitiesDescriptor getEntitiesDescriptor(String entitiesID) throws MetadataProviderException; + + @Override + EntityDescriptor getEntityDescriptor(String entityID) throws MetadataProviderException; + + @Override + List<RoleDescriptor> getRole(String entityID, QName roleName) throws MetadataProviderException; + + @Override + RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol) + throws MetadataProviderException; + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IRefreshableMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IRefreshableMetadataProvider.java index 2f9e5fea..74ee74de 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IRefreshableMetadataProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/metadata/IRefreshableMetadataProvider.java @@ -1,42 +1,37 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.api.metadata; /** + * Metadata provider that supports dynamic refreshing on external events. + * * @author tlenz * */ public interface IRefreshableMetadataProvider { - /** - * Refresh a entity or load a entity in a metadata provider - * - * @param entityID - * @return true, if refresh is success, otherwise false - */ - public boolean refreshMetadataProvider(String entityID); + /** + * Refresh a entity or load a entity in a metadata provider. + * + * @param entityID EntityId + * @return true, if refresh is success, otherwise false + */ + public boolean refreshMetadataProvider(String entityID); } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EAAFRequestedAttribute.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EAAFRequestedAttribute.java deleted file mode 100644 index 0501a990..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EAAFRequestedAttribute.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api.reqattr; - -import java.util.List; - -import javax.xml.namespace.QName; - -import org.opensaml.common.SAMLObject; -import org.opensaml.xml.AttributeExtensibleXMLObject; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.schema.XSBooleanValue; - -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; - -public interface EAAFRequestedAttribute extends SAMLObject, AttributeExtensibleXMLObject , org.opensaml.saml2.metadata.RequestedAttribute{ - - /** Element local name. */ - String DEF_LOCAL_NAME = "RequestedAttribute"; - - /** Local name of the XSI type. */ - String TYPE_LOCAL_NAME = "RequestedAttributeAbstractType"; - - - /** Default element name. */ - QName DEFAULT_ELEMENT_NAME = new QName(PVPConstants.EIDAT10_SAML_NS, DEF_LOCAL_NAME, - PVPConstants.EIDAT10_PREFIX); - - /** QName of the XSI type. */ - QName TYPE_NAME = new QName(PVPConstants.EIDAT10_SAML_NS, TYPE_LOCAL_NAME, - PVPConstants.EIDAT10_PREFIX); - - - - /** NAME_ATTRIB_NAME attribute name. */ - String NAME_ATTRIB_NAME = "Name"; - - /** NAME_FORMAT_ATTRIB_NAME attribute name. */ - String NAME_FORMAT_ATTR = "NameFormat"; - - /** IS_REQUIRED_ATTRIB_NAME attribute name. */ - String IS_REQUIRED_ATTR = "isRequired"; - - /** FRIENDLY_NAME_ATTRIB_NAME attribute name. */ - String FRIENDLY_NAME_ATT = "FriendlyName"; - - /** Unspecified attribute format ID. */ - String UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"; - - /** URI reference attribute format ID. */ - String URI_REFERENCE = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"; - - /** Basic attribute format ID. */ - String BASIC = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"; - - /** - * Gets the name. - * - * @return the name - */ - String getName(); - - /** - * Sets the name. - * - * @param name the new name - */ - void setName(String name); - - /** - * Gets the name format. - * - * @return the name format - */ - String getNameFormat(); - - /** - * Sets the name format. - * - * @param nameFormat the new name format - */ - void setNameFormat(String nameFormat); - - /** - * Gets the friendly name. - * - * @return the friendly name - */ - String getFriendlyName(); - - /** - * Sets the friendly name. - * - * @param friendlyName the new friendly name - */ - void setFriendlyName(String friendlyName); - -/* *//** - * Gets the checks if is required. - * - * @return the checks if is required - *//* - String isRequired();*/ - - /** - * Gets the checks if is required xs boolean. - * - * @return the checks if is required xs boolean - */ - String getIsRequiredXSBoolean(); - - /** - * Sets the checks if is required. - * - * @param newIsRequired the new checks if is required - */ - void setIsRequired(String newIsRequired); - - /** - * Gets the attribute values. - * - * @return the attribute values - */ - List<XMLObject> getAttributeValues(); - - XSBooleanValue isRequiredXSBoolean(); - - void setIsRequired(Boolean aBoolean); - - void setIsRequired(XSBooleanValue xsBooleanValue); - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EAAFRequestedAttributes.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EAAFRequestedAttributes.java deleted file mode 100644 index 768d5c36..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EAAFRequestedAttributes.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api.reqattr; - -import java.util.List; - -import javax.xml.namespace.QName; - -import org.opensaml.common.SAMLObject; - -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; - -public interface EAAFRequestedAttributes extends SAMLObject { - /** The Constant DEFAULT_ELEMENT_LOCAL_NAME. */ - String DEF_LOCAL_NAME = "RequestedAttributes"; - - /** Default element name. */ - QName DEFAULT_ELEMENT_NAME = new QName(PVPConstants.EIDAT10_SAML_NS, DEF_LOCAL_NAME, - PVPConstants.EIDAT10_PREFIX); - - /** Local name of the XSI type. */ - String TYPE_LOCAL_NAME = "RequestedAttributesType"; - - /** QName of the XSI type. */ - QName TYPE_NAME = new QName(PVPConstants.EIDAT10_SAML_NS, TYPE_LOCAL_NAME, - PVPConstants.EIDAT10_PREFIX); - - /** - * Gets the attributes. - * - * @return the attributes - */ - List<EAAFRequestedAttribute> getAttributes(); -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EaafRequestedAttribute.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EaafRequestedAttribute.java new file mode 100644 index 00000000..f44a545d --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EaafRequestedAttribute.java @@ -0,0 +1,150 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api.reqattr; + +import java.util.List; +import javax.xml.namespace.QName; +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import org.opensaml.common.SAMLObject; +import org.opensaml.xml.AttributeExtensibleXMLObject; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.schema.XSBooleanValue; + +public interface EaafRequestedAttribute extends SAMLObject, AttributeExtensibleXMLObject, + org.opensaml.saml2.metadata.RequestedAttribute { + + /** Element local name. */ + String DEF_LOCAL_NAME = "RequestedAttribute"; + + /** Local name of the XSI type. */ + String TYPE_LOCAL_NAME = "RequestedAttributeAbstractType"; + + + /** Default element name. */ + QName DEFAULT_ELEMENT_NAME = + new QName(PvpConstants.EIDAT10_SAML_NS, DEF_LOCAL_NAME, PvpConstants.EIDAT10_PREFIX); + + /** QName of the XSI type. */ + QName TYPE_NAME = + new QName(PvpConstants.EIDAT10_SAML_NS, TYPE_LOCAL_NAME, PvpConstants.EIDAT10_PREFIX); + + + + /** NAME_ATTRIB_NAME attribute name. */ + String NAME_ATTRIB_NAME = "Name"; + + /** NAME_FORMAT_ATTRIB_NAME attribute name. */ + String NAME_FORMAT_ATTR = "NameFormat"; + + /** IS_REQUIRED_ATTRIB_NAME attribute name. */ + String IS_REQUIRED_ATTR = "isRequired"; + + /** FRIENDLY_NAME_ATTRIB_NAME attribute name. */ + String FRIENDLY_NAME_ATT = "FriendlyName"; + + /** Unspecified attribute format ID. */ + String UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"; + + /** URI reference attribute format ID. */ + String URI_REFERENCE = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"; + + /** Basic attribute format ID. */ + String BASIC = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"; + + /** + * Gets the name. + * + * @return the name + */ + @Override + String getName(); + + /** + * Sets the name. + * + * @param name the new name + */ + @Override + void setName(String name); + + /** + * Gets the name format. + * + * @return the name format + */ + @Override + String getNameFormat(); + + /** + * Sets the name format. + * + * @param nameFormat the new name format + */ + @Override + void setNameFormat(String nameFormat); + + /** + * Gets the friendly name. + * + * @return the friendly name + */ + @Override + String getFriendlyName(); + + /** + * Sets the friendly name. + * + * @param friendlyName the new friendly name + */ + @Override + void setFriendlyName(String friendlyName); + + /** + * Gets the checks if is required xs boolean. + * + * @return the checks if is required xs boolean + */ + String getIsRequiredXsBoolean(); + + @Override + void setIsRequired(Boolean aboolean); + + @Override + void setIsRequired(XSBooleanValue xsBooleanValue); + + /** + * Sets the checks if is required. + * + * @param newIsRequired the new checks if is required + */ + void setIsRequired(String newIsRequired); + + /** + * Gets the attribute values. + * + * @return the attribute values + */ + @Override + List<XMLObject> getAttributeValues(); + + @Override + XSBooleanValue isRequiredXSBoolean(); + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EaafRequestedAttributes.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EaafRequestedAttributes.java new file mode 100644 index 00000000..98f118b0 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/reqattr/EaafRequestedAttributes.java @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api.reqattr; + +import java.util.List; + +import javax.xml.namespace.QName; + +import org.opensaml.common.SAMLObject; + +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; + +public interface EaafRequestedAttributes extends SAMLObject { + /** The Constant DEFAULT_ELEMENT_LOCAL_NAME. */ + String DEF_LOCAL_NAME = "RequestedAttributes"; + + /** Default element name. */ + QName DEFAULT_ELEMENT_NAME = + new QName(PvpConstants.EIDAT10_SAML_NS, DEF_LOCAL_NAME, PvpConstants.EIDAT10_PREFIX); + + /** Local name of the XSI type. */ + String TYPE_LOCAL_NAME = "RequestedAttributesType"; + + /** QName of the XSI type. */ + QName TYPE_NAME = + new QName(PvpConstants.EIDAT10_SAML_NS, TYPE_LOCAL_NAME, PvpConstants.EIDAT10_PREFIX); + + /** + * Gets the attributes. + * + * @return the attributes + */ + List<EaafRequestedAttribute> getAttributes(); +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/IAuthnRequestValidator.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/IAuthnRequestValidator.java index 439543fe..41dcd3b9 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/IAuthnRequestValidator.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/IAuthnRequestValidator.java @@ -1,39 +1,33 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.api.validation; import javax.servlet.http.HttpServletRequest; - -import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.metadata.SPSSODescriptor; - import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException; +import org.opensaml.saml2.core.AuthnRequest; +import org.opensaml.saml2.metadata.SPSSODescriptor; public interface IAuthnRequestValidator { - void validate(HttpServletRequest httpReq, IRequest pendingReq, AuthnRequest authReq, SPSSODescriptor spSSODescriptor) throws AuthnRequestValidatorException; + void validate(HttpServletRequest httpReq, IRequest pendingReq, AuthnRequest authReq, + SPSSODescriptor spSsoDescriptor) throws AuthnRequestValidatorException; -}
\ No newline at end of file +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/ISAMLValidator.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/ISAMLValidator.java deleted file mode 100644 index 4b8ddea6..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/ISAMLValidator.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.api.validation; - -import org.opensaml.saml2.core.RequestAbstractType; - -import at.gv.egiz.eaaf.core.exceptions.EAAFException; - -public interface ISAMLValidator { - public void validateRequest(RequestAbstractType request) throws EAAFException; -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/ISamlValidator.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/ISamlValidator.java new file mode 100644 index 00000000..3cbe59da --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/api/validation/ISamlValidator.java @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.api.validation; + +import org.opensaml.saml2.core.RequestAbstractType; + +import at.gv.egiz.eaaf.core.exceptions.EaafException; + +public interface ISamlValidator { + void validateRequest(RequestAbstractType request) throws EaafException; +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/AttributQueryException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/AttributQueryException.java index 189dc91e..82fb2c79 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/AttributQueryException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/AttributQueryException.java @@ -1,48 +1,35 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.exception; -/** - * @author tlenz - * - */ -public class AttributQueryException extends PVP2Exception { +public class AttributQueryException extends Pvp2Exception { + + + private static final long serialVersionUID = -4302422507173728748L; - /** - * - */ - private static final long serialVersionUID = -4302422507173728748L; + public AttributQueryException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } - public AttributQueryException(String messageId, Object[] parameters) { - super(messageId, parameters); - } - - public AttributQueryException(String messageId, Object[] parameters, Throwable e) { - super(messageId, parameters, e); - } + public AttributQueryException(final String messageId, final Object[] parameters, final Throwable e) { + super(messageId, parameters, e); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/BindingNotSupportedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/BindingNotSupportedException.java index d966e4a1..97971d3a 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/BindingNotSupportedException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/BindingNotSupportedException.java @@ -1,45 +1,38 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.exception; import org.opensaml.saml2.core.StatusCode; -public class BindingNotSupportedException extends PVP2Exception { +public class BindingNotSupportedException extends Pvp2Exception { + + private static final long serialVersionUID = -7227603941387879360L; + + public BindingNotSupportedException(final String binding) { + super("pvp2.11", new Object[] {binding}); + this.statusCodeValue = StatusCode.UNSUPPORTED_BINDING_URI; + } + + + - public BindingNotSupportedException(String binding) { - super("pvp2.11", new Object[] {binding}); - this.statusCodeValue = StatusCode.UNSUPPORTED_BINDING_URI; - } - /** - * - */ - private static final long serialVersionUID = -7227603941387879360L; - - } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/CredentialsNotAvailableException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/CredentialsNotAvailableException.java index e079cdef..ae64e134 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/CredentialsNotAvailableException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/CredentialsNotAvailableException.java @@ -1,48 +1,40 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. + */ + package at.gv.egiz.eaaf.modules.pvp2.exception; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; + +public class CredentialsNotAvailableException extends EaafException { + + private static final long serialVersionUID = -2564476345552842599L; + + public CredentialsNotAvailableException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + + public CredentialsNotAvailableException(final String messageId, final Object[] parameters, + final Throwable e) { + super(messageId, parameters, e); + } -public class CredentialsNotAvailableException extends EAAFException { - public CredentialsNotAvailableException(String messageId, - Object[] parameters) { - super(messageId, parameters); - } - public CredentialsNotAvailableException(String messageId, - Object[] parameters, Throwable e) { - super(messageId, parameters, e); - } - - /** - * - */ - private static final long serialVersionUID = -2564476345552842599L; } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidDateFormatException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidDateFormatException.java index 6bcddf8a..8ca373c4 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidDateFormatException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidDateFormatException.java @@ -1,43 +1,35 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.exception; import org.opensaml.saml2.core.StatusCode; -public class InvalidDateFormatException extends PVP2Exception { +public class InvalidDateFormatException extends Pvp2Exception { + + private static final long serialVersionUID = -6867976890237846085L; + + public InvalidDateFormatException() { + super("pvp2.02", null); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } - public InvalidDateFormatException() { - super("pvp2.02", null); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - /** - * - */ - private static final long serialVersionUID = -6867976890237846085L; } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidPVPRequestException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidPVPRequestException.java deleted file mode 100644 index 1d79ae2e..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidPVPRequestException.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -public class InvalidPVPRequestException extends PVP2Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public InvalidPVPRequestException(String messageId, Object[] parameters) { - super(messageId, parameters); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidPvpRequestException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidPvpRequestException.java new file mode 100644 index 00000000..e13731d6 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/InvalidPvpRequestException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +public class InvalidPvpRequestException extends Pvp2Exception { + + private static final long serialVersionUID = 1L; + + public InvalidPvpRequestException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NameIDFormatNotSupportedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NameIDFormatNotSupportedException.java deleted file mode 100644 index a5ff811d..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NameIDFormatNotSupportedException.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -import org.opensaml.saml2.core.StatusCode; - -import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException; - -public class NameIDFormatNotSupportedException extends AuthnRequestValidatorException { - - public NameIDFormatNotSupportedException(String nameIDFormat) { - super("pvp2.12", new Object[] {nameIDFormat}); - statusCodeValue = StatusCode.INVALID_NAMEID_POLICY_URI; - - } - - /** - * - */ - private static final long serialVersionUID = -2270762519437873336L; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NameIdFormatNotSupportedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NameIdFormatNotSupportedException.java new file mode 100644 index 00000000..b43db603 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NameIdFormatNotSupportedException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException; +import org.opensaml.saml2.core.StatusCode; + +public class NameIdFormatNotSupportedException extends AuthnRequestValidatorException { + + private static final long serialVersionUID = -2270762519437873336L; + + /** + * Invalid nameIdFormat in SAML2 request. + * + * @param nameIdFormat requested NameIdFormat + */ + public NameIdFormatNotSupportedException(final String nameIdFormat) { + super("pvp2.12", new Object[] {nameIdFormat}); + statusCodeValue = StatusCode.INVALID_NAMEID_POLICY_URI; + + } + + + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NoMetadataInformationException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NoMetadataInformationException.java index e600a1c7..f22d2d17 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NoMetadataInformationException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/NoMetadataInformationException.java @@ -1,43 +1,36 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.exception; import org.opensaml.saml2.core.StatusCode; -public class NoMetadataInformationException extends PVP2Exception { +public class NoMetadataInformationException extends Pvp2Exception { + + private static final long serialVersionUID = -4608068445208032193L; + + public NoMetadataInformationException() { + super("pvp2.15", null); + this.statusCodeValue = StatusCode.UNKNOWN_PRINCIPAL_URI; + } + - public NoMetadataInformationException() { - super("pvp2.15", null); - this.statusCodeValue = StatusCode.UNKNOWN_PRINCIPAL_URI; - } - /** - * - */ - private static final long serialVersionUID = -4608068445208032193L; } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/PVP2Exception.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/PVP2Exception.java deleted file mode 100644 index cfe4ca9d..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/PVP2Exception.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -import org.opensaml.saml2.core.StatusCode; - -import at.gv.egiz.eaaf.core.exceptions.EAAFException; - -public abstract class PVP2Exception extends EAAFException { - //TODO:!!!!! - - protected String statusCodeValue = StatusCode.RESPONDER_URI; - protected String statusMessageValue = null; - - public PVP2Exception(String messageId, Object[] parameters, - Throwable wrapped) { - super(messageId, parameters, wrapped); - this.statusMessageValue = this.getMessage(); - } - - public PVP2Exception(String messageId, Object[] parameters) { - super(messageId, parameters); - this.statusMessageValue = this.getMessage(); - } - - - public String getStatusCodeValue() { - return (this.statusCodeValue); - } - - public String getStatusMessageValue() { - return (this.statusMessageValue); - } - - /** - * - */ - private static final long serialVersionUID = 7669537952484421069L; - - - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/PVP2MetadataException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/PVP2MetadataException.java deleted file mode 100644 index 379fe19f..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/PVP2MetadataException.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -public class PVP2MetadataException extends PVP2Exception { - - private static final long serialVersionUID = 1L; - - public PVP2MetadataException(String messageId, Object[] parameters) { - super(messageId, parameters); - } - - public PVP2MetadataException(String messageId, Object[] parameters, Throwable wrapped) { - super(messageId, parameters, wrapped); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/Pvp2Exception.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/Pvp2Exception.java new file mode 100644 index 00000000..93980a73 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/Pvp2Exception.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import org.opensaml.saml2.core.StatusCode; + +public abstract class Pvp2Exception extends EaafException { + private static final long serialVersionUID = 7669537952484421069L; + + protected String statusCodeValue = StatusCode.RESPONDER_URI; + protected String statusMessageValue = null; + + public Pvp2Exception(final String messageId, final Object[] parameters, final Throwable wrapped) { + super(messageId, parameters, wrapped); + this.statusMessageValue = this.getMessage(); + } + + public Pvp2Exception(final String messageId, final Object[] parameters) { + super(messageId, parameters); + this.statusMessageValue = this.getMessage(); + } + + + public String getStatusCodeValue() { + return (this.statusCodeValue); + } + + public String getStatusMessageValue() { + return (this.statusMessageValue); + } + + + + + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/Pvp2MetadataException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/Pvp2MetadataException.java new file mode 100644 index 00000000..ab0e8871 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/Pvp2MetadataException.java @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +public class Pvp2MetadataException extends Pvp2Exception { + + private static final long serialVersionUID = 1L; + + public Pvp2MetadataException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + + public Pvp2MetadataException(final String messageId, final Object[] parameters, final Throwable wrapped) { + super(messageId, parameters, wrapped); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QAANotAllowedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QAANotAllowedException.java deleted file mode 100644 index a8012d85..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QAANotAllowedException.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -import org.opensaml.saml2.core.StatusCode; - - -public class QAANotAllowedException extends PVP2Exception { - - public QAANotAllowedException(String qaa_auth, String qaa_request, String mode) { - super("pvp2.17", new Object[] {qaa_auth, qaa_request, mode}); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - - /** - * - */ - private static final long serialVersionUID = -3964192953884089323L; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QAANotSupportedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QAANotSupportedException.java deleted file mode 100644 index 0b53ae23..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QAANotSupportedException.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -import org.opensaml.saml2.core.StatusCode; - - -public class QAANotSupportedException extends PVP2Exception { - - public QAANotSupportedException(String qaa) { - super("pvp2.05", new Object[] {qaa}); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - - /** - * - */ - private static final long serialVersionUID = -3964192953884089323L; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QaaNotAllowedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QaaNotAllowedException.java new file mode 100644 index 00000000..9edba3f2 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QaaNotAllowedException.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +import org.opensaml.saml2.core.StatusCode; + + +public class QaaNotAllowedException extends Pvp2Exception { + + private static final long serialVersionUID = -3964192953884089323L; + + public QaaNotAllowedException(final String qaaAuth, final String qaaRequest, final String mode) { + super("pvp2.17", new Object[] {qaaAuth, qaaRequest, mode}); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QaaNotSupportedException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QaaNotSupportedException.java new file mode 100644 index 00000000..dc48508d --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/QaaNotSupportedException.java @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +import org.opensaml.saml2.core.StatusCode; + + +public class QaaNotSupportedException extends Pvp2Exception { + + private static final long serialVersionUID = -3964192953884089323L; + + public QaaNotSupportedException(final String qaa) { + super("pvp2.05", new Object[] {qaa}); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } + + + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SAMLMetadataSignatureException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SAMLMetadataSignatureException.java deleted file mode 100644 index 9e35871d..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SAMLMetadataSignatureException.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.exception; - -import org.opensaml.saml2.core.StatusCode; - -public class SAMLMetadataSignatureException extends PVP2Exception { - - public SAMLMetadataSignatureException() { - super("pvp2.25", null); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - - public SAMLMetadataSignatureException(Throwable e) { - super("pvp2.25", null, e); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - - /** - * - */ - private static final long serialVersionUID = 1L; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMetadataSignatureException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMetadataSignatureException.java new file mode 100644 index 00000000..ede310f0 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMetadataSignatureException.java @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.exception; + +import org.opensaml.saml2.core.StatusCode; + +public class SamlMetadataSignatureException extends Pvp2Exception { + private static final long serialVersionUID = 1L; + + public SamlMetadataSignatureException() { + super("pvp2.25", null); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } + + public SamlMetadataSignatureException(final Throwable e) { + super("pvp2.25", null, e); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } + + + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SchemaValidationException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SchemaValidationException.java index f9adbf6d..39cf148b 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SchemaValidationException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SchemaValidationException.java @@ -1,56 +1,35 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.exception; -/** - * @author tlenz - * - */ -public class SchemaValidationException extends PVP2Exception { +public class SchemaValidationException extends Pvp2Exception { + + private static final long serialVersionUID = 1L; + - /** - * - */ - private static final long serialVersionUID = 1L; + public SchemaValidationException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } - /** - * @param messageId - * @param parameters - */ - public SchemaValidationException(String messageId, Object[] parameters) { - super(messageId, parameters); - } - - /** - * @param messageId - * @param parameters - */ - public SchemaValidationException(String messageId, Object[] parameters, Throwable e) { - super(messageId, parameters, e); - } + public SchemaValidationException(final String messageId, final Object[] parameters, final Throwable e) { + super(messageId, parameters, e); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SignatureValidationException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SignatureValidationException.java index 1f1f46e5..410686f6 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SignatureValidationException.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SignatureValidationException.java @@ -1,62 +1,43 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.exception; import org.opensaml.saml2.metadata.provider.FilterException; -/** - * @author tlenz - * - */ public class SignatureValidationException extends FilterException { - /** - * @param string - */ - public SignatureValidationException(String string) { - super(string); - - } - - /** - * @param e - */ - public SignatureValidationException(Exception e) { - super(e); - } - - /** - * @param string - * @param object - */ - public SignatureValidationException(String string, Exception e) { - super(string, e); - } - - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; + + public SignatureValidationException(final String string) { + super(string); + + } + + public SignatureValidationException(final Exception e) { + super(e); + } + + public SignatureValidationException(final String string, final Exception e) { + super(string, e); + } + + } 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 index 79578788..0933f0a2 100644 --- 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 @@ -1,34 +1,43 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.binding; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfigurationFactory; +import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration; +import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiFormBuilder; +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; import org.apache.commons.lang3.StringUtils; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; @@ -57,186 +66,174 @@ 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.IGUIBuilderConfigurationFactory; -import at.gv.egiz.eaaf.core.api.gui.IVelocityGUIBuilderConfiguration; -import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiFormBuilder; -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) IVelocityGuiFormBuilder guiBuilder; - @Autowired(required=true) IGUIBuilderConfigurationFactory guiConfigFactory; - - @Override - 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 - final IVelocityGUIBuilderConfiguration guiConfig = guiConfigFactory.getSPSpecificSAML2PostConfiguration( - pendingReq, - "pvp_postbinding_template.html", - authConfig.getConfigurationRootDirectory()); - - final HTTPPostEncoderWithOwnTemplate encoder = new HTTPPostEncoderWithOwnTemplate(guiConfig, guiBuilder, - VelocityProvider.getClassPathVelocityEngine()); - - //set OpenSAML2 process parameter into binding context dao - final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - resp, true); - final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - final 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 (final Exception e) { - log.warn("Can not encode SAML2 request", e); - throw new SecurityException(e); - - } - } - - @Override - 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 - final IVelocityGUIBuilderConfiguration guiConfig = guiConfigFactory.getSPSpecificSAML2PostConfiguration( - pendingReq, - "pvp_postbinding_template.html", - authConfig.getConfigurationRootDirectory()); - final HTTPPostEncoderWithOwnTemplate encoder = new HTTPPostEncoderWithOwnTemplate(guiConfig, guiBuilder, - VelocityProvider.getClassPathVelocityEngine()); - - //set OpenSAML2 process parameter into binding context dao - final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - resp, true); - final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - final 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 (final Exception e) { - log.warn("Can not encode SAML2 response", e); - throw new SecurityException(e); - - } - } - - @Override - public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, - SecurityException { - - final HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); - final 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); - - //set security policy context - final BasicSecurityPolicy policy = new BasicSecurityPolicy(); - policy.getPolicyRules().add( - new PVPSignedRequestPolicyRule(metadataProvider, - TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider), - messageContext.getPeerEntityRole())); - final SecurityPolicyResolver secResolver = new StaticSecurityPolicyResolver(policy); - messageContext.setSecurityPolicyResolver(secResolver); - - decode.decode(messageContext); - - InboundMessage msg = null; - if (messageContext.getInboundMessage() instanceof RequestAbstractType) { - final RequestAbstractType inboundMessage = (RequestAbstractType) messageContext - .getInboundMessage(); - msg = new PVPSProfileRequest(inboundMessage, getSAML2BindingName()); - msg.setEntityID(inboundMessage.getIssuer().getValue()); - - } else if (messageContext.getInboundMessage() instanceof StatusResponseType){ - final 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; - } - - @Override - public boolean handleDecode(String action, HttpServletRequest req) { - return (req.getMethod().equals("POST") && action.equals(PVPConstants.POST)); - } - - @Override - public String getSAML2BindingName() { - return SAMLConstants.SAML2_POST_BINDING_URI; - } + private static final Logger log = LoggerFactory.getLogger(PostBinding.class); + + @Autowired(required = true) + IConfiguration authConfig; + @Autowired(required = true) + IVelocityGuiFormBuilder guiBuilder; + @Autowired(required = true) + IGuiBuilderConfigurationFactory guiConfigFactory; + + @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 { + + try { + // load default PVP security configurations + EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + + // initialize POST binding encoder with template decoration + final IVelocityGuiBuilderConfiguration guiConfig = + guiConfigFactory.getSpSpecificSaml2PostConfiguration(pendingReq, + "pvp_postbinding_template.html", authConfig.getConfigurationRootDirectory()); + + final HttpPostEncoderWithOwnTemplate encoder = new HttpPostEncoderWithOwnTemplate(guiConfig, + guiBuilder, VelocityProvider.getClassPathVelocityEngine()); + + // set OpenSAML2 process parameter into binding context dao + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(resp, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final 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 (final Exception e) { + log.warn("Can not encode SAML2 request", e); + throw new SecurityException(e); + + } + } + + @Override + public void encodeRespone(final HttpServletRequest req, final HttpServletResponse resp, + final StatusResponseType response, final String targetLocation, final String relayState, + final Credential credentials, final 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 + final IVelocityGuiBuilderConfiguration guiConfig = + guiConfigFactory.getSpSpecificSaml2PostConfiguration(pendingReq, + "pvp_postbinding_template.html", authConfig.getConfigurationRootDirectory()); + final HttpPostEncoderWithOwnTemplate encoder = new HttpPostEncoderWithOwnTemplate(guiConfig, + guiBuilder, VelocityProvider.getClassPathVelocityEngine()); + + // set OpenSAML2 process parameter into binding context dao + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(resp, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final 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 (final Exception e) { + log.warn("Can not encode SAML2 response", e); + throw new SecurityException(e); + + } + } + + @Override + public InboundMessageInterface decode(final HttpServletRequest req, + final HttpServletResponse resp, final MetadataProvider metadataProvider, + final boolean isSpEndPoint, final URIComparator comparator) + throws MessageDecodingException, SecurityException { + + final HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); + final BasicSAMLMessageContext<SAMLObject, ?, ?> 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 + final BasicSecurityPolicy policy = new BasicSecurityPolicy(); + policy.getPolicyRules() + .add(new PvpSignedRequestPolicyRule(metadataProvider, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider), + messageContext.getPeerEntityRole())); + final SecurityPolicyResolver secResolver = new StaticSecurityPolicyResolver(policy); + messageContext.setSecurityPolicyResolver(secResolver); + + decode.decode(messageContext); + + InboundMessage msg = null; + if (messageContext.getInboundMessage() instanceof RequestAbstractType) { + final RequestAbstractType inboundMessage = + (RequestAbstractType) messageContext.getInboundMessage(); + msg = new PvpSProfileRequest(inboundMessage, getSaml2BindingName()); + msg.setEntityID(inboundMessage.getIssuer().getValue()); + + } else if (messageContext.getInboundMessage() instanceof StatusResponseType) { + final 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; + } + + @Override + public boolean handleDecode(final String action, final HttpServletRequest req) { + return (req.getMethod().equals("POST") && action.equals(PvpConstants.POST)); + } + + @Override + public String getSaml2BindingName() { + return SAMLConstants.SAML2_POST_BINDING_URI; + } } 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 index ca9b3d98..4e548d57 100644 --- 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 @@ -1,34 +1,38 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.binding; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - +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; import org.apache.commons.lang3.StringUtils; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; @@ -58,182 +62,179 @@ 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; - } + + private static final Logger log = LoggerFactory.getLogger(RedirectBinding.class); + + @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 { + + // load default PVP security configurations + EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + + log.debug("create SAML RedirectBinding response"); + + final HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(resp, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final 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); + } + + @Override + public void encodeRespone(final HttpServletRequest req, final HttpServletResponse resp, + final StatusResponseType response, final String targetLocation, final String relayState, + final Credential credentials, final IRequest pendingReq) + throws MessageEncodingException, SecurityException { + + // load default PVP security configurations + EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + + log.debug("create SAML RedirectBinding response"); + + final HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(resp, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final 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); + + } + + @Override + public InboundMessageInterface decode(final HttpServletRequest req, + final HttpServletResponse resp, final MetadataProvider metadataProvider, + final boolean isSpEndPoint, final URIComparator comparator) + throws MessageDecodingException, SecurityException { + + final HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder(new BasicParserPool()); + + final BasicSAMLMessageContext<SAMLObject, ?, ?> 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); + + final SAML2HTTPRedirectDeflateSignatureRule signatureRule = + new SAML2HTTPRedirectDeflateSignatureRule( + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + final PvpAuthRequestSignedRole signedRole = new PvpAuthRequestSignedRole(); + final BasicSecurityPolicy policy = new BasicSecurityPolicy(); + policy.getPolicyRules().add(signedRole); + policy.getPolicyRules().add(signatureRule); + final 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 (final 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) { + final RequestAbstractType inboundMessage = + (RequestAbstractType) messageContext.getInboundMessage(); + msg = new PvpSProfileRequest(inboundMessage, getSaml2BindingName()); + + + } else if (messageContext.getInboundMessage() instanceof StatusResponseType) { + final 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; + } + + @Override + public boolean handleDecode(final String action, final HttpServletRequest req) { + return ((action.equals(PvpConstants.REDIRECT) || action.equals(PvpConstants.SINGLELOGOUT)) + && req.getMethod().equals("GET")); + } + + @Override + public String getSaml2BindingName() { + return SAMLConstants.SAML2_REDIRECT_BINDING_URI; + } } 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 c70060ad..79a88487 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 @@ -1,36 +1,36 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.binding; import java.util.List; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - +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.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 org.apache.commons.lang3.StringUtils; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; @@ -56,117 +56,112 @@ 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.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; - @Service("PVPSOAPBinding") public class SoapBinding implements IDecoder, IEncoder { - private static final Logger log = LoggerFactory.getLogger(SoapBinding.class); - public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, - SecurityException, PVP2Exception { - HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); - BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = - new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - 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); - - Envelope inboundMessage = (Envelope) messageContext - .getInboundMessage(); - - if (inboundMessage.getBody() != null) { - List<XMLObject> xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); - - if (!xmlElemList.isEmpty()) { - SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); - PVPSProfileRequest request = new PVPSProfileRequest(attrReq, getSAML2BindingName()); - - if (messageContext.getPeerEntityMetadata() != null) - request.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); - - else if (attrReq instanceof RequestAbstractType) { - 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 (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); - } - - public boolean handleDecode(String action, HttpServletRequest req) { - return (req.getMethod().equals("POST") && - (action.equals(PVPConstants.SOAP) || action.equals(PVPConstants.ATTRIBUTEQUERY))); - } - - public void encodeRequest(HttpServletRequest req, HttpServletResponse resp, - RequestAbstractType request, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) - throws MessageEncodingException, SecurityException, PVP2Exception { - - } - - public void encodeRespone(HttpServletRequest req, HttpServletResponse resp, - StatusResponseType response, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) - throws MessageEncodingException, SecurityException, PVP2Exception { - - //load default PVP security configurations - EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); - - HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); - HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - resp, true); - BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - context.setOutboundSAMLMessageSigningCredential(credentials); - context.setOutboundSAMLMessage(response); - context.setOutboundMessageTransport(responseAdapter); - - encoder.encode(context); - - } - - public String getSAML2BindingName() { - return SAMLConstants.SAML2_SOAP11_BINDING_URI; - } + private static final Logger log = LoggerFactory.getLogger(SoapBinding.class); + + @Override + public InboundMessageInterface decode(final HttpServletRequest req, + final HttpServletResponse resp, final MetadataProvider 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; + + } + } + + log.error("Receive empty PVP 2.1 attributequery request."); + throw new AttributQueryException("Receive empty PVP 2.1 attributequery request.", null); + } + + @Override + public boolean handleDecode(final String action, final HttpServletRequest req) { + return (req.getMethod().equals("POST") + && (action.equals(PvpConstants.SOAP) || action.equals(PvpConstants.ATTRIBUTEQUERY))); + } + + @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 { + + } + + @Override + public void encodeRespone(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 { + + // load default PVP security configurations + EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + + 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); + + encoder.encode(context); + + } + + @Override + public String getSaml2BindingName() { + return SAMLConstants.SAML2_SOAP11_BINDING_URI; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/CitizenTokenBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/CitizenTokenBuilder.java index c38b04bd..9765f520 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/CitizenTokenBuilder.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/CitizenTokenBuilder.java @@ -1,31 +1,25 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.builder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeValue; import org.opensaml.xml.Configuration; @@ -35,87 +29,118 @@ import org.opensaml.xml.schema.XSString; import org.opensaml.xml.schema.impl.XSIntegerBuilder; import org.opensaml.xml.schema.impl.XSStringBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - +/** + * Build all attributes from PVP2 citizen-token. + * + * @author tlenz + * + */ public class CitizenTokenBuilder { - public static XMLObject buildAttributeStringValue(String value) { - XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); - XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); - stringValue.setValue(value); - return stringValue; - } - - public static XMLObject buildAttributeIntegerValue(int value) { - XSIntegerBuilder integerBuilder = (XSIntegerBuilder) Configuration.getBuilderFactory().getBuilder(XSInteger.TYPE_NAME); - XSInteger integerValue = integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME); - integerValue.setValue(value); - return integerValue; - } - - public static Attribute buildStringAttribute(String friendlyName, - String name, String value) { - Attribute attribute = - SAML2Utils.createSAMLObject(Attribute.class); - attribute.setFriendlyName(friendlyName); - attribute.setName(name); - attribute.getAttributeValues().add(buildAttributeStringValue(value)); - return attribute; - } - - public static Attribute buildIntegerAttribute(String friendlyName, - String name, int value) { - Attribute attribute = - SAML2Utils.createSAMLObject(Attribute.class); - attribute.setFriendlyName(friendlyName); - attribute.setName(name); - attribute.getAttributeValues().add(buildAttributeIntegerValue(value)); - return attribute; - } - - public static Attribute buildPVPVersion(String value) { - return buildStringAttribute("PVP-VERSION", - "urn:oid:1.2.40.0.10.2.1.1.261.10", value); - } - - public static Attribute buildSecClass(int value) { - return buildIntegerAttribute("SECCLASS", - "", value); - } - - public static Attribute buildPrincipalName(String value) { - return buildStringAttribute("PRINCIPAL-NAME", - "urn:oid:1.2.40.0.10.2.1.1.261.20", value); - } - - public static Attribute buildGivenName(String value) { - return buildStringAttribute("GIVEN-NAME", - "urn:oid:2.5.4.42", value); - } - - public static Attribute buildBirthday(String value) { - return buildStringAttribute("BIRTHDATE", - "urn:oid:1.2.40.0.10.2.1.1.55", value); - } - - public static Attribute buildBPK(String value) { - return buildStringAttribute("BPK", - "urn:oid:1.2.40.0.10.2.1.1.149", value); - } - - public static Attribute buildEID_CITIZEN_QAALEVEL(int value) { - return buildIntegerAttribute("EID-CITIZEN-QAA-LEVEL", - "urn:oid:1.2.40.0.10.2.1.1.261.94", value); - } - - public static Attribute buildEID_ISSUING_NATION(String value) { - return buildStringAttribute("EID-ISSUING-NATION", - "urn:oid:1.2.40.0.10.2.1.1.261.32", value); - } - - public static Attribute buildEID_SECTOR_FOR_IDENTIFIER(String value) { - return buildStringAttribute("EID-SECTOR-FOR-IDENTIFIER", - "urn:oid:1.2.40.0.10.2.1.1.261.34", value); - } - + /** + * Build simple attribute. + * + * @param value Attributevalue + * @return XML attribute + */ + public static XMLObject buildAttributeStringValue(final String value) { + final XSStringBuilder stringBuilder = + (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); + final XSString stringValue = + stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); + stringValue.setValue(value); + return stringValue; + } + + /** + * Build simple attribute. + * + * @param value Attributevalue + * @return XML attribute + */ + public static XMLObject buildAttributeIntegerValue(final int value) { + final XSIntegerBuilder integerBuilder = + (XSIntegerBuilder) Configuration.getBuilderFactory().getBuilder(XSInteger.TYPE_NAME); + final XSInteger integerValue = + integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME); + integerValue.setValue(value); + return integerValue; + } + + /** + * Build simple attribute. + * + * @param friendlyName attribute friendly-name + * @param value Attributevalue + * @return XML attribute + */ + public static Attribute buildStringAttribute(final String friendlyName, final String name, + final String value) { + final Attribute attribute = Saml2Utils.createSamlObject(Attribute.class); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.getAttributeValues().add(buildAttributeStringValue(value)); + return attribute; + } + + /** + * Build simple attribute. + * + * @param friendlyName attribute friendly-name + * @param value Attributevalue + * @return XML attribute + */ + public static Attribute buildIntegerAttribute(final String friendlyName, final String name, + final int value) { + final Attribute attribute = Saml2Utils.createSamlObject(Attribute.class); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.getAttributeValues().add(buildAttributeIntegerValue(value)); + return attribute; + } + + /** + * Build PVP version attribute. + * + * @param value PVP Version + * @return SAML2 Attribute + */ + public static Attribute buildPvpVersion(final String value) { + return buildStringAttribute("PVP-VERSION", "urn:oid:1.2.40.0.10.2.1.1.261.10", value); + } + + public static Attribute buildSecClass(final int value) { + return buildIntegerAttribute("SECCLASS", "", value); + } + + public static Attribute buildPrincipalName(final String value) { + return buildStringAttribute("PRINCIPAL-NAME", "urn:oid:1.2.40.0.10.2.1.1.261.20", value); + } + + public static Attribute buildGivenName(final String value) { + return buildStringAttribute("GIVEN-NAME", "urn:oid:2.5.4.42", value); + } + + public static Attribute buildBirthday(final String value) { + return buildStringAttribute("BIRTHDATE", "urn:oid:1.2.40.0.10.2.1.1.55", value); + } + + public static Attribute buildBpk(final String value) { + return buildStringAttribute("BPK", "urn:oid:1.2.40.0.10.2.1.1.149", value); + } + + public static Attribute buildEid_Citizen_QaaLevel(final int value) { + return buildIntegerAttribute("EID-CITIZEN-QAA-LEVEL", "urn:oid:1.2.40.0.10.2.1.1.261.94", + value); + } + + public static Attribute buildEid_Issuing_Nation(final String value) { + return buildStringAttribute("EID-ISSUING-NATION", "urn:oid:1.2.40.0.10.2.1.1.261.32", value); + } + + public static Attribute buildEid_Sector_For_Identifier(final String value) { + return buildStringAttribute("EID-SECTOR-FOR-IDENTIFIER", "urn:oid:1.2.40.0.10.2.1.1.261.34", + value); + } + } 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 deleted file mode 100644 index 0d9e38e0..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PVPAttributeBuilder.java +++ /dev/null @@ -1,221 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -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.saml2.core.Attribute; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder; -import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; -import at.gv.egiz.eaaf.core.api.idp.IAuthData; -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.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; - -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(IAttributeBuilder builder) { - builders.put(builder.getName(), builder); - } - - static { - builders = new HashMap<String, IAttributeBuilder>(); - - log.info("Loading protocol attribut-builder modules:"); - if (attributBuilderLoader != null ) { - Iterator<IAttributeBuilder> moduleLoaderInterator = attributBuilderLoader.iterator(); - while (moduleLoaderInterator.hasNext()) { - try { - IAttributeBuilder modul = moduleLoaderInterator.next(); - log.info("Loading attribut-builder Modul Information: " + modul.getName()); - addBuilder(modul); - - } catch(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(String name) { - return builders.get(name); - - } - - public static Attribute buildAttribute(String name, ISPConfiguration oaParam, - IAuthData authData) throws PVP2Exception, AttributeBuilderException { - if (builders.containsKey(name)) { - try { - return builders.get(name).build(oaParam, authData, generator); - } - catch (AttributeBuilderException e) { - if (e instanceof UnavailableAttributeException) { - throw e; - - } else if (e instanceof InvalidDateFormatAttributeException) { - throw new InvalidDateFormatException(); - - } else { - throw new UnavailableAttributeException(name); - - } - } - } - return null; - } - - public static Attribute buildEmptyAttribute(String name) { - if (builders.containsKey(name)) { - return builders.get(name).buildEmpty(generator); - } - return null; - } - - public static Attribute buildAttribute(String name, String value) { - if (builders.containsKey(name)) { - return builders.get(name).buildEmpty(generator); - } - return null; - } - - - /** - * Return all attributes that has a {@link PVPMETADATA} annotation - * - * @return - */ - public static List<Attribute> buildSupportedEmptyAttributes() { - List<Attribute> attributes = new ArrayList<Attribute>(); - Iterator<IAttributeBuilder> builderIt = builders.values().iterator(); - while (builderIt.hasNext()) { - IAttributeBuilder builder = builderIt.next(); - if (builder.getClass().isAnnotationPresent(PVPMETADATA.class)) { - Attribute emptyAttribute = builder.buildEmpty(generator); - if (emptyAttribute != null) { - attributes.add(emptyAttribute); - } - - } else { - log.trace(builder.getName() + "is no PVP Metadata attribute"); - - } - } - return attributes; - } - - public static RequestedAttribute buildReqAttribute(String name, String friendlyName, boolean required) { - RequestedAttribute attribute = SAML2Utils.createSAMLObject(RequestedAttribute.class); - attribute.setIsRequired(required); - attribute.setName(name); - attribute.setFriendlyName(friendlyName); - attribute.setNameFormat(Attribute.URI_REFERENCE); - return attribute; - } - - /** - * Build a set of PVP Response-Attributes - * <br><br> - * <b>INFO:</b> If a specific attribute can not be build, a info is logged, but no execpetion is thrown. - * Therefore, the return List must not include all requested attributes. - * - * @param authData AuthenticationData <code>IAuthData</code> which is used to build the attribute values, but never <code>null</code> - * @param reqAttributenName List of PVP attribute names which are requested, but never <code>null</code> - * @return List of PVP attributes, but never <code>null</code> - */ - public static List<Attribute> buildSetOfResponseAttributes(IAuthData authData, - Collection<String> reqAttributenName) { - List<Attribute> attrList = new ArrayList<Attribute>(); - if (reqAttributenName != null) { - Iterator<String> it = reqAttributenName.iterator(); - while (it.hasNext()) { - String reqAttributName = it.next(); - try { - Attribute attr = PVPAttributeBuilder.buildAttribute( - reqAttributName, null, authData); - if (attr == null) { - log.info( - "Attribute generation failed! for " - + reqAttributName); - - } else { - attrList.add(attr); - - } - - } catch (PVP2Exception e) { - log.info( - "Attribute generation failed! for " - + reqAttributName); - - } catch (Exception e) { - log.warn( - "General Attribute generation failed! for " - + reqAttributName, e); - - } - } - } - - return attrList; - } - - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PVPMetadataBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PVPMetadataBuilder.java deleted file mode 100644 index 61c6006b..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PVPMetadataBuilder.java +++ /dev/null @@ -1,450 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.Collection; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.apache.commons.httpclient.auth.CredentialsNotAvailableException; -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.opensaml.Configuration; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.metadata.AssertionConsumerService; -import org.opensaml.saml2.metadata.AttributeConsumingService; -import org.opensaml.saml2.metadata.ContactPerson; -import org.opensaml.saml2.metadata.EntitiesDescriptor; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.IDPSSODescriptor; -import org.opensaml.saml2.metadata.KeyDescriptor; -import org.opensaml.saml2.metadata.LocalizedString; -import org.opensaml.saml2.metadata.NameIDFormat; -import org.opensaml.saml2.metadata.Organization; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.opensaml.saml2.metadata.RoleDescriptor; -import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.opensaml.saml2.metadata.ServiceName; -import org.opensaml.saml2.metadata.SingleLogoutService; -import org.opensaml.saml2.metadata.SingleSignOnService; -import org.opensaml.xml.io.Marshaller; -import org.opensaml.xml.io.MarshallingException; -import org.opensaml.xml.security.SecurityException; -import org.opensaml.xml.security.SecurityHelper; -import org.opensaml.xml.security.credential.Credential; -import org.opensaml.xml.security.credential.UsageType; -import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; -import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; -import org.opensaml.xml.signature.Signature; -import org.opensaml.xml.signature.SignatureException; -import org.opensaml.xml.signature.Signer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.w3c.dom.Document; - -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataBuilderConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EAAFDefaultSAML2Bootstrap; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - -/** - * @author tlenz - * - */ - -@Service("PVPMetadataBuilder") -public class PVPMetadataBuilder { - - private static final Logger log = LoggerFactory.getLogger(PVPMetadataBuilder.class); - - X509KeyInfoGeneratorFactory keyInfoFactory = null; - - /** - * - */ - public PVPMetadataBuilder() { - keyInfoFactory = new X509KeyInfoGeneratorFactory(); - keyInfoFactory.setEmitEntityIDAsKeyName(true); - keyInfoFactory.setEmitEntityCertificate(true); - - } - - - /** - * - * Build PVP 2.1 conform SAML2 metadata - * - * @param config - * PVPMetadataBuilder configuration - * - * @return PVP metadata as XML String - * @throws SecurityException - * @throws ConfigurationException - * @throws CredentialsNotAvailableException - * @throws TransformerFactoryConfigurationError - * @throws MarshallingException - * @throws TransformerException - * @throws ParserConfigurationException - * @throws IOException - * @throws SignatureException - */ - public String buildPVPMetadata(IPVPMetadataBuilderConfiguration config) throws CredentialsNotAvailableException, EAAFException, SecurityException, TransformerFactoryConfigurationError, MarshallingException, TransformerException, ParserConfigurationException, IOException, SignatureException { - DateTime date = new DateTime(); - EntityDescriptor entityDescriptor = SAML2Utils - .createSAMLObject(EntityDescriptor.class); - - //set entityID - entityDescriptor.setEntityID(config.getEntityID()); - - //set contact and organisation information - List<ContactPerson> contactPersons = config.getContactPersonInformation(); - if (contactPersons != null) - entityDescriptor.getContactPersons().addAll(contactPersons); - - Organization organisation = config.getOrgansiationInformation(); - if (organisation != null) - entityDescriptor.setOrganization(organisation); - - //set IDP metadata - if (config.buildIDPSSODescriptor()) { - RoleDescriptor idpSSODesc = generateIDPMetadata(config); - if (idpSSODesc != null) - entityDescriptor.getRoleDescriptors().add(idpSSODesc); - - } - - //set SP metadata for interfederation - if (config.buildSPSSODescriptor()) { - RoleDescriptor spSSODesc = generateSPMetadata(config); - if (spSSODesc != null) - entityDescriptor.getRoleDescriptors().add(spSSODesc); - - } - - //set metadata signature parameters - Credential metadataSignCred = config.getMetadataSigningCredentials(); - Signature signature = AbstractCredentialProvider.getIDPSignature(metadataSignCred); - SecurityHelper.prepareSignatureParams(signature, metadataSignCred, null, null); - - //initialize XML document builder - DocumentBuilder builder; - DocumentBuilderFactory factory = DocumentBuilderFactory - .newInstance(); - - builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - - - //build entities descriptor - if (config.buildEntitiesDescriptorAsRootElement()) { - EntitiesDescriptor entitiesDescriptor = - SAML2Utils.createSAMLObject(EntitiesDescriptor.class); - entitiesDescriptor.setName(config.getEntityFriendlyName()); - entitiesDescriptor.setID(SAML2Utils.getSecureIdentifier()); - entitiesDescriptor.setValidUntil(date.plusHours(config.getMetadataValidUntil())); - entitiesDescriptor.getEntityDescriptors().add(entityDescriptor); - - //load default PVP security configurations - EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); - entitiesDescriptor.setSignature(signature); - - - //marshall document - Marshaller out = Configuration.getMarshallerFactory() - .getMarshaller(entitiesDescriptor); - out.marshall(entitiesDescriptor, document); - - } else { - entityDescriptor.setValidUntil(date.plusHours(config.getMetadataValidUntil())); - entityDescriptor.setID(SAML2Utils.getSecureIdentifier()); - - entityDescriptor.setSignature(signature); - - - - //marshall document - Marshaller out = Configuration.getMarshallerFactory() - .getMarshaller(entityDescriptor); - out.marshall(entityDescriptor, document); - - } - - //sign metadata - Signer.signObject(signature); - - //transform metadata object to XML string - Transformer transformer = TransformerFactory.newInstance() - .newTransformer(); - - StringWriter sw = new StringWriter(); - StreamResult sr = new StreamResult(sw); - DOMSource source = new DOMSource(document); - transformer.transform(source, sr); - sw.close(); - - return sw.toString(); - } - - - private RoleDescriptor generateSPMetadata(IPVPMetadataBuilderConfiguration config) throws CredentialsNotAvailableException, SecurityException, EAAFException { - SPSSODescriptor spSSODescriptor = SAML2Utils.createSAMLObject(SPSSODescriptor.class); - spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); - spSSODescriptor.setAuthnRequestsSigned(config.wantAuthnRequestSigned()); - spSSODescriptor.setWantAssertionsSigned(config.wantAssertionSigned()); - - KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); - - //Set AuthRequest Signing certificate - Credential authcredential = config.getRequestorResponseSigningCredentials(); - if (authcredential == null) { - log.warn("SP Metadata generation FAILED! --> Builder has NO request signing-credential. "); - return null; - - } else { - KeyDescriptor signKeyDescriptor = SAML2Utils - .createSAMLObject(KeyDescriptor.class); - signKeyDescriptor.setUse(UsageType.SIGNING); - signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential)); - spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); - - } - - //Set assertion encryption credentials - Credential authEncCredential = config.getEncryptionCredentials(); - - if (authEncCredential != null) { - KeyDescriptor encryKeyDescriptor = SAML2Utils - .createSAMLObject(KeyDescriptor.class); - encryKeyDescriptor.setUse(UsageType.ENCRYPTION); - encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential)); - spSSODescriptor.getKeyDescriptors().add(encryKeyDescriptor); - - } else { - log.warn("No Assertion Encryption-Key defined. This setting is not recommended!"); - - } - - //check nameID formates - if (config.getSPAllowedNameITTypes() == null || config.getSPAllowedNameITTypes().size() == 0) { - log.warn("SP Metadata generation FAILED! --> Builder has NO provideable SAML2 nameIDFormats. "); - return null; - - } else { - for (String format : config.getSPAllowedNameITTypes()) { - NameIDFormat nameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); - nameIDFormat.setFormat(format); - spSSODescriptor.getNameIDFormats().add(nameIDFormat); - - } - } - - - //add POST-Binding assertion consumer services - if (StringUtils.isNotEmpty(config.getSPAssertionConsumerServicePostBindingURL())) { - AssertionConsumerService postassertionConsumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class); - postassertionConsumerService.setIndex(0); - postassertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); - postassertionConsumerService.setLocation(config.getSPAssertionConsumerServicePostBindingURL()); - postassertionConsumerService.setIsDefault(true); - spSSODescriptor.getAssertionConsumerServices().add(postassertionConsumerService); - - } - - //add POST-Binding assertion consumer services - if (StringUtils.isNotEmpty(config.getSPAssertionConsumerServiceRedirectBindingURL())) { - AssertionConsumerService redirectassertionConsumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class); - redirectassertionConsumerService.setIndex(1); - redirectassertionConsumerService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - redirectassertionConsumerService.setLocation(config.getSPAssertionConsumerServiceRedirectBindingURL()); - spSSODescriptor.getAssertionConsumerServices().add(redirectassertionConsumerService); - - } - - //validate WebSSO endpoints - if (spSSODescriptor.getAssertionConsumerServices().size() == 0) { - log.warn("SP Metadata generation FAILED! --> NO SAML2 AssertionConsumerService endpoint found. "); - return null; - - } - - //add POST-Binding SLO descriptor - if (StringUtils.isNotEmpty(config.getSPSLOPostBindingURL())) { - SingleLogoutService postSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - postSLOService.setLocation(config.getSPSLOPostBindingURL()); - postSLOService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); - spSSODescriptor.getSingleLogoutServices().add(postSLOService); - - } - - //add POST-Binding SLO descriptor - if (StringUtils.isNotEmpty(config.getSPSLORedirectBindingURL())) { - SingleLogoutService redirectSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - redirectSLOService.setLocation(config.getSPSLORedirectBindingURL()); - redirectSLOService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - spSSODescriptor.getSingleLogoutServices().add(redirectSLOService); - - } - - //add POST-Binding SLO descriptor - if (StringUtils.isNotEmpty(config.getSPSLOSOAPBindingURL())) { - SingleLogoutService soapSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - soapSLOService.setLocation(config.getSPSLOSOAPBindingURL()); - soapSLOService.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); - spSSODescriptor.getSingleLogoutServices().add(soapSLOService); - - } - - - //add required attributes - Collection<RequestedAttribute> reqSPAttr = config.getSPRequiredAttributes(); - AttributeConsumingService attributeService = SAML2Utils.createSAMLObject(AttributeConsumingService.class); - - attributeService.setIndex(0); - attributeService.setIsDefault(true); - ServiceName serviceName = SAML2Utils.createSAMLObject(ServiceName.class); - serviceName.setName(new LocalizedString("Default Service", "en")); - attributeService.getNames().add(serviceName); - - if (reqSPAttr != null && reqSPAttr.size() > 0) { - log.debug("Add " + reqSPAttr.size() + " attributes to SP metadata"); - attributeService.getRequestAttributes().addAll(reqSPAttr); - - } else { - log.debug("SP metadata contains NO requested attributes."); - - } - - spSSODescriptor.getAttributeConsumingServices().add(attributeService); - - return spSSODescriptor; - } - - private IDPSSODescriptor generateIDPMetadata(IPVPMetadataBuilderConfiguration config) throws EAAFException, CredentialsNotAvailableException, SecurityException { - //check response signing credential - Credential responseSignCred = config.getRequestorResponseSigningCredentials(); - if (responseSignCred == null) { - log.warn("IDP Metadata generation FAILED! --> Builder has NO Response signing credential. "); - return null; - - } - - //check nameID formates - if (config.getIDPPossibleNameITTypes() == null || config.getIDPPossibleNameITTypes().size() == 0) { - log.warn("IDP Metadata generation FAILED! --> Builder has NO provideable SAML2 nameIDFormats. "); - return null; - - } - - // build SAML2 IDP-SSO descriptor element - IDPSSODescriptor idpSSODescriptor = SAML2Utils - .createSAMLObject(IDPSSODescriptor.class); - - idpSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); - - //set ass default value, because PVP 2.x specification defines this feature as MUST - idpSSODescriptor.setWantAuthnRequestsSigned(config.wantAuthnRequestSigned()); - - // add WebSSO descriptor for POST-Binding - if (StringUtils.isNotEmpty(config.getIDPWebSSOPostBindingURL())) { - SingleSignOnService postSingleSignOnService = SAML2Utils.createSAMLObject(SingleSignOnService.class); - postSingleSignOnService.setLocation(config.getIDPWebSSOPostBindingURL()); - postSingleSignOnService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); - idpSSODescriptor.getSingleSignOnServices().add(postSingleSignOnService); - - } - - // add WebSSO descriptor for Redirect-Binding - if (StringUtils.isNotEmpty(config.getIDPWebSSORedirectBindingURL())) { - SingleSignOnService postSingleSignOnService = SAML2Utils.createSAMLObject(SingleSignOnService.class); - postSingleSignOnService.setLocation(config.getIDPWebSSORedirectBindingURL()); - postSingleSignOnService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - idpSSODescriptor.getSingleSignOnServices().add(postSingleSignOnService); - - } - - //add Single LogOut POST-Binding endpoing - if (StringUtils.isNotEmpty(config.getIDPSLOPostBindingURL())) { - SingleLogoutService postSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - postSLOService.setLocation(config.getIDPSLOPostBindingURL()); - postSLOService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); - idpSSODescriptor.getSingleLogoutServices().add(postSLOService); - - } - - //add Single LogOut Redirect-Binding endpoing - if (StringUtils.isNotEmpty(config.getIDPSLORedirectBindingURL())) { - SingleLogoutService redirectSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - redirectSLOService.setLocation(config.getIDPSLORedirectBindingURL()); - redirectSLOService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - idpSSODescriptor.getSingleLogoutServices().add(redirectSLOService); - - } - - //validate WebSSO endpoints - if (idpSSODescriptor.getSingleSignOnServices().size() == 0) { - log.warn("IDP Metadata generation FAILED! --> NO SAML2 SingleSignOnService endpoint found. "); - return null; - - } - - //set assertion signing key - KeyDescriptor signKeyDescriptor = SAML2Utils - .createSAMLObject(KeyDescriptor.class); - signKeyDescriptor.setUse(UsageType.SIGNING); - KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); - signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(config.getRequestorResponseSigningCredentials())); - idpSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); - - //set IDP attribute set - idpSSODescriptor.getAttributes().addAll(config.getIDPPossibleAttributes()); - - //set providable nameID formats - for (String format : config.getIDPPossibleNameITTypes()) { - NameIDFormat nameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); - nameIDFormat.setFormat(format); - idpSSODescriptor.getNameIDFormats().add(nameIDFormat); - - } - - return idpSSODescriptor; - - } - -} 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 new file mode 100644 index 00000000..73ba73c7 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpAttributeBuilder.java @@ -0,0 +1,244 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +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 at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder; +import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +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.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 org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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. + * + * @param name attribute name + * @param value attribute value + * @return SAML2 attribute + */ + 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); + } + return null; + } + + /** + * Build a SAML2 attribute. + * + * @param name attribute name + * @param oaParam Service-Provider configuration + * @param authData serice-provider specific authentication data + * @return SAML2 attribute + * @throws Pvp2Exception In case of a general error + * @throws AttributeBuilderException In case of an attribute builder error + */ + public static Attribute buildAttribute(final String name, final IspConfiguration oaParam, + final IAuthData authData) throws Pvp2Exception, AttributeBuilderException { + if (builders.containsKey(name)) { + try { + return builders.get(name).build(oaParam, authData, generator); + } catch (final AttributeBuilderException e) { + if (e instanceof UnavailableAttributeException) { + throw e; + + } else if (e instanceof InvalidDateFormatAttributeException) { + throw new InvalidDateFormatException(); + + } else { + throw new UnavailableAttributeException(name); + + } + } + } + return null; + } + + /** + * Build an empty attribute. + * + * @param name attributename + * @return SAML2 attribute + */ + public static Attribute buildEmptyAttribute(final String name) { + if (builders.containsKey(name)) { + return builders.get(name).buildEmpty(generator); + } + return null; + } + + + + + + /** + * Return all attributes that has a {@link PvpMetadata} annotation. + * + * @return + */ + public static List<Attribute> buildSupportedEmptyAttributes() { + final List<Attribute> attributes = new ArrayList<>(); + final Iterator<IAttributeBuilder> builderIt = builders.values().iterator(); + while (builderIt.hasNext()) { + final IAttributeBuilder builder = builderIt.next(); + if (builder.getClass().isAnnotationPresent(PvpMetadata.class)) { + final Attribute emptyAttribute = builder.buildEmpty(generator); + if (emptyAttribute != null) { + attributes.add(emptyAttribute); + } + + } else { + log.trace(builder.getName() + "is no PVP Metadata attribute"); + + } + } + return attributes; + } + + /** + * Build a requested attribute. + * + * @param name attribute name + * @param friendlyName attribute friendlyname + * @param required is attribute mandatory + * @return SAML2 requested attribute + */ + public static RequestedAttribute buildReqAttribute(final String name, final String friendlyName, + final boolean required) { + final RequestedAttribute attribute = Saml2Utils.createSamlObject(RequestedAttribute.class); + attribute.setIsRequired(required); + attribute.setName(name); + attribute.setFriendlyName(friendlyName); + attribute.setNameFormat(Attribute.URI_REFERENCE); + return attribute; + } + + /** + * Build a set of PVP Response-Attributes <br> + * <br> + * <b>INFO:</b> If a specific attribute can not be build, a info is logged, but no execpetion is + * thrown. Therefore, the return List must not include all requested attributes. + * + * @param authData AuthenticationData <code>IAuthData</code> which is used to build the attribute + * values, but never <code>null</code> + * @param reqAttributenName List of PVP attribute names which are requested, but never + * <code>null</code> + * @return List of PVP attributes, but never <code>null</code> + */ + public static List<Attribute> buildSetOfResponseAttributes(final IAuthData authData, + final Collection<String> reqAttributenName) { + final List<Attribute> attrList = new ArrayList<>(); + if (reqAttributenName != null) { + final Iterator<String> it = reqAttributenName.iterator(); + while (it.hasNext()) { + final String reqAttributName = it.next(); + try { + final Attribute attr = + PvpAttributeBuilder.buildAttribute(reqAttributName, null, authData); + if (attr == null) { + log.info("Attribute generation failed! for " + reqAttributName); + + } else { + attrList.add(attr); + + } + + } catch (final Pvp2Exception e) { + log.info("Attribute generation failed! for " + reqAttributName); + + } catch (final Exception e) { + log.warn("General Attribute generation failed! for " + reqAttributName, e); + + } + } + } + + return attrList; + } + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpMetadataBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpMetadataBuilder.java new file mode 100644 index 00000000..1efa8745 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/PvpMetadataBuilder.java @@ -0,0 +1,458 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collection; +import java.util.List; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafDefaultSaml2Bootstrap; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import org.apache.commons.httpclient.auth.CredentialsNotAvailableException; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.AttributeConsumingService; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.KeyDescriptor; +import org.opensaml.saml2.metadata.LocalizedString; +import org.opensaml.saml2.metadata.NameIDFormat; +import org.opensaml.saml2.metadata.Organization; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.saml2.metadata.RoleDescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.ServiceName; +import org.opensaml.saml2.metadata.SingleLogoutService; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.SecurityHelper; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.credential.UsageType; +import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; +import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureException; +import org.opensaml.xml.signature.Signer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.w3c.dom.Document; + +/** + * PVP metadata builder implementation. + * + * @author tlenz + * + */ + +@Service("PVPMetadataBuilder") +public class PvpMetadataBuilder { + + private static final Logger log = LoggerFactory.getLogger(PvpMetadataBuilder.class); + + X509KeyInfoGeneratorFactory keyInfoFactory = null; + + /** + * PVP metadata builder. + * + */ + public PvpMetadataBuilder() { + keyInfoFactory = new X509KeyInfoGeneratorFactory(); + keyInfoFactory.setEmitEntityIDAsKeyName(true); + keyInfoFactory.setEmitEntityCertificate(true); + + } + + + /** + * Build PVP 2.1 conform SAML2 metadata. + * + * @param config PVPMetadataBuilder configuration* + * @return PVP metadata as XML String + * @throws SecurityException In case of an error + * @throws ConfigurationException In case of an error + * @throws CredentialsNotAvailableException In case of an error + * @throws TransformerFactoryConfigurationError In case of an error + * @throws MarshallingException In case of an error + * @throws TransformerException In case of an error + * @throws ParserConfigurationException In case of an error + * @throws IOException In case of an error + * @throws SignatureException In case of an error + */ + public String buildPvpMetadata(final IPvpMetadataBuilderConfiguration config) + throws CredentialsNotAvailableException, EaafException, SecurityException, + TransformerFactoryConfigurationError, MarshallingException, TransformerException, + ParserConfigurationException, IOException, SignatureException { + final DateTime date = new DateTime(); + final EntityDescriptor entityDescriptor = Saml2Utils.createSamlObject(EntityDescriptor.class); + + // set entityID + entityDescriptor.setEntityID(config.getEntityID()); + + // set contact and organisation information + final List<ContactPerson> contactPersons = config.getContactPersonInformation(); + if (contactPersons != null) { + entityDescriptor.getContactPersons().addAll(contactPersons); + } + + final Organization organisation = config.getOrgansiationInformation(); + if (organisation != null) { + entityDescriptor.setOrganization(organisation); + } + + // set IDP metadata + if (config.buildIdpSsoDescriptor()) { + final RoleDescriptor idpSsoDesc = generateIdpMetadata(config); + if (idpSsoDesc != null) { + entityDescriptor.getRoleDescriptors().add(idpSsoDesc); + } + + } + + // set SP metadata for interfederation + if (config.buildSpSsoDescriptor()) { + final RoleDescriptor spSsoDesc = generateSpMetadata(config); + if (spSsoDesc != null) { + entityDescriptor.getRoleDescriptors().add(spSsoDesc); + } + + } + + // set metadata signature parameters + final Credential metadataSignCred = config.getMetadataSigningCredentials(); + final Signature signature = AbstractCredentialProvider.getIdpSignature(metadataSignCred); + SecurityHelper.prepareSignatureParams(signature, metadataSignCred, null, null); + + // initialize XML document builder + DocumentBuilder builder; + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + builder = factory.newDocumentBuilder(); + final Document document = builder.newDocument(); + + + // build entities descriptor + if (config.buildEntitiesDescriptorAsRootElement()) { + final EntitiesDescriptor entitiesDescriptor = + Saml2Utils.createSamlObject(EntitiesDescriptor.class); + entitiesDescriptor.setName(config.getEntityFriendlyName()); + entitiesDescriptor.setID(Saml2Utils.getSecureIdentifier()); + entitiesDescriptor.setValidUntil(date.plusHours(config.getMetadataValidUntil())); + entitiesDescriptor.getEntityDescriptors().add(entityDescriptor); + + // load default PVP security configurations + EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + entitiesDescriptor.setSignature(signature); + + + // marshall document + final Marshaller out = + org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller(entitiesDescriptor); + out.marshall(entitiesDescriptor, document); + + } else { + entityDescriptor.setValidUntil(date.plusHours(config.getMetadataValidUntil())); + entityDescriptor.setID(Saml2Utils.getSecureIdentifier()); + + entityDescriptor.setSignature(signature); + + + + // marshall document + final Marshaller out = + org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller(entityDescriptor); + out.marshall(entityDescriptor, document); + + } + + // sign metadata + Signer.signObject(signature); + + // transform metadata object to XML string + final Transformer transformer = TransformerFactory.newInstance().newTransformer(); + + final StringWriter sw = new StringWriter(); + final StreamResult sr = new StreamResult(sw); + final DOMSource source = new DOMSource(document); + transformer.transform(source, sr); + sw.close(); + + return sw.toString(); + } + + + private RoleDescriptor generateSpMetadata(final IPvpMetadataBuilderConfiguration config) + throws CredentialsNotAvailableException, SecurityException, EaafException { + final SPSSODescriptor spSsoDescriptor = Saml2Utils.createSamlObject(SPSSODescriptor.class); + spSsoDescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); + spSsoDescriptor.setAuthnRequestsSigned(config.wantAuthnRequestSigned()); + spSsoDescriptor.setWantAssertionsSigned(config.wantAssertionSigned()); + + final KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); + + // Set AuthRequest Signing certificate + final Credential authcredential = config.getRequestorResponseSigningCredentials(); + if (authcredential == null) { + log.warn("SP Metadata generation FAILED! --> Builder has NO request signing-credential. "); + return null; + + } else { + final KeyDescriptor signKeyDescriptor = Saml2Utils.createSamlObject(KeyDescriptor.class); + signKeyDescriptor.setUse(UsageType.SIGNING); + signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential)); + spSsoDescriptor.getKeyDescriptors().add(signKeyDescriptor); + + } + + // Set assertion encryption credentials + final Credential authEncCredential = config.getEncryptionCredentials(); + + if (authEncCredential != null) { + final KeyDescriptor encryKeyDescriptor = Saml2Utils.createSamlObject(KeyDescriptor.class); + encryKeyDescriptor.setUse(UsageType.ENCRYPTION); + encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential)); + spSsoDescriptor.getKeyDescriptors().add(encryKeyDescriptor); + + } else { + log.warn("No Assertion Encryption-Key defined. This setting is not recommended!"); + + } + + // check nameID formates + if (config.getSpAllowedNameIdTypes() == null || config.getSpAllowedNameIdTypes().size() == 0) { + log.warn( + "SP Metadata generation FAILED! --> Builder has NO provideable SAML2 nameIDFormats. "); + return null; + + } else { + for (final String format : config.getSpAllowedNameIdTypes()) { + final NameIDFormat nameIdFormat = Saml2Utils.createSamlObject(NameIDFormat.class); + nameIdFormat.setFormat(format); + spSsoDescriptor.getNameIDFormats().add(nameIdFormat); + + } + } + + + // add POST-Binding assertion consumer services + if (StringUtils.isNotEmpty(config.getSpAssertionConsumerServicePostBindingUrl())) { + final AssertionConsumerService postassertionConsumerService = + Saml2Utils.createSamlObject(AssertionConsumerService.class); + postassertionConsumerService.setIndex(0); + postassertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + postassertionConsumerService + .setLocation(config.getSpAssertionConsumerServicePostBindingUrl()); + postassertionConsumerService.setIsDefault(true); + spSsoDescriptor.getAssertionConsumerServices().add(postassertionConsumerService); + + } + + // add POST-Binding assertion consumer services + if (StringUtils.isNotEmpty(config.getSpAssertionConsumerServiceRedirectBindingUrl())) { + final AssertionConsumerService redirectassertionConsumerService = + Saml2Utils.createSamlObject(AssertionConsumerService.class); + redirectassertionConsumerService.setIndex(1); + redirectassertionConsumerService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + redirectassertionConsumerService + .setLocation(config.getSpAssertionConsumerServiceRedirectBindingUrl()); + spSsoDescriptor.getAssertionConsumerServices().add(redirectassertionConsumerService); + + } + + // validate WebSSO endpoints + if (spSsoDescriptor.getAssertionConsumerServices().size() == 0) { + log.warn( + "SP Metadata generation FAILED! --> NO SAML2 AssertionConsumerService endpoint found. "); + return null; + + } + + // add POST-Binding SLO descriptor + if (StringUtils.isNotEmpty(config.getSpSloPostBindingUrl())) { + final SingleLogoutService postSloService = + Saml2Utils.createSamlObject(SingleLogoutService.class); + postSloService.setLocation(config.getSpSloPostBindingUrl()); + postSloService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + spSsoDescriptor.getSingleLogoutServices().add(postSloService); + + } + + // add POST-Binding SLO descriptor + if (StringUtils.isNotEmpty(config.getSpSloRedirectBindingUrl())) { + final SingleLogoutService redirectSloService = + Saml2Utils.createSamlObject(SingleLogoutService.class); + redirectSloService.setLocation(config.getSpSloRedirectBindingUrl()); + redirectSloService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + spSsoDescriptor.getSingleLogoutServices().add(redirectSloService); + + } + + // add POST-Binding SLO descriptor + if (StringUtils.isNotEmpty(config.getSpSloSoapBindingUrl())) { + final SingleLogoutService soapSloService = + Saml2Utils.createSamlObject(SingleLogoutService.class); + soapSloService.setLocation(config.getSpSloSoapBindingUrl()); + soapSloService.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); + spSsoDescriptor.getSingleLogoutServices().add(soapSloService); + + } + + + // add required attributes + final Collection<RequestedAttribute> reqSpAttr = config.getSpRequiredAttributes(); + final AttributeConsumingService attributeService = + Saml2Utils.createSamlObject(AttributeConsumingService.class); + + attributeService.setIndex(0); + attributeService.setIsDefault(true); + final ServiceName serviceName = Saml2Utils.createSamlObject(ServiceName.class); + serviceName.setName(new LocalizedString("Default Service", "en")); + attributeService.getNames().add(serviceName); + + if (reqSpAttr != null && reqSpAttr.size() > 0) { + log.debug("Add " + reqSpAttr.size() + " attributes to SP metadata"); + attributeService.getRequestAttributes().addAll(reqSpAttr); + + } else { + log.debug("SP metadata contains NO requested attributes."); + + } + + spSsoDescriptor.getAttributeConsumingServices().add(attributeService); + + return spSsoDescriptor; + } + + private IDPSSODescriptor generateIdpMetadata(final IPvpMetadataBuilderConfiguration config) + throws EaafException, CredentialsNotAvailableException, SecurityException { + // check response signing credential + final Credential responseSignCred = config.getRequestorResponseSigningCredentials(); + if (responseSignCred == null) { + log.warn("IDP Metadata generation FAILED! --> Builder has NO Response signing credential. "); + return null; + + } + + // check nameID formates + if (config.getIdpPossibleNameIdTypes() == null + || config.getIdpPossibleNameIdTypes().size() == 0) { + log.warn( + "IDP Metadata generation FAILED! --> Builder has NO provideable SAML2 nameIDFormats. "); + return null; + + } + + // build SAML2 IDP-SSO descriptor element + final IDPSSODescriptor idpSsoDescriptor = Saml2Utils.createSamlObject(IDPSSODescriptor.class); + + idpSsoDescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); + + // set ass default value, because PVP 2.x specification defines this feature as MUST + idpSsoDescriptor.setWantAuthnRequestsSigned(config.wantAuthnRequestSigned()); + + // add WebSSO descriptor for POST-Binding + if (StringUtils.isNotEmpty(config.getIdpWebSsoPostBindingUrl())) { + final SingleSignOnService postSingleSignOnService = + Saml2Utils.createSamlObject(SingleSignOnService.class); + postSingleSignOnService.setLocation(config.getIdpWebSsoPostBindingUrl()); + postSingleSignOnService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + idpSsoDescriptor.getSingleSignOnServices().add(postSingleSignOnService); + + } + + // add WebSSO descriptor for Redirect-Binding + if (StringUtils.isNotEmpty(config.getIdpWebSsoRedirectBindingUrl())) { + final SingleSignOnService postSingleSignOnService = + Saml2Utils.createSamlObject(SingleSignOnService.class); + postSingleSignOnService.setLocation(config.getIdpWebSsoRedirectBindingUrl()); + postSingleSignOnService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + idpSsoDescriptor.getSingleSignOnServices().add(postSingleSignOnService); + + } + + // add Single LogOut POST-Binding endpoing + if (StringUtils.isNotEmpty(config.getIdpSloPostBindingUrl())) { + final SingleLogoutService postSloService = + Saml2Utils.createSamlObject(SingleLogoutService.class); + postSloService.setLocation(config.getIdpSloPostBindingUrl()); + postSloService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + idpSsoDescriptor.getSingleLogoutServices().add(postSloService); + + } + + // add Single LogOut Redirect-Binding endpoing + if (StringUtils.isNotEmpty(config.getIdpSloRedirectBindingUrl())) { + final SingleLogoutService redirectSloService = + Saml2Utils.createSamlObject(SingleLogoutService.class); + redirectSloService.setLocation(config.getIdpSloRedirectBindingUrl()); + redirectSloService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + idpSsoDescriptor.getSingleLogoutServices().add(redirectSloService); + + } + + // validate WebSSO endpoints + if (idpSsoDescriptor.getSingleSignOnServices().size() == 0) { + log.warn("IDP Metadata generation FAILED! --> NO SAML2 SingleSignOnService endpoint found. "); + return null; + + } + + // set assertion signing key + final KeyDescriptor signKeyDescriptor = Saml2Utils.createSamlObject(KeyDescriptor.class); + signKeyDescriptor.setUse(UsageType.SIGNING); + final KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); + signKeyDescriptor + .setKeyInfo(keyInfoGenerator.generate(config.getRequestorResponseSigningCredentials())); + idpSsoDescriptor.getKeyDescriptors().add(signKeyDescriptor); + + // set IDP attribute set + idpSsoDescriptor.getAttributes().addAll(config.getIdpPossibleAttributes()); + + // set providable nameID formats + for (final String format : config.getIdpPossibleNameIdTypes()) { + final NameIDFormat nameIdFormat = Saml2Utils.createSamlObject(NameIDFormat.class); + nameIdFormat.setFormat(format); + idpSsoDescriptor.getNameIDFormats().add(nameIdFormat); + + } + + return idpSsoDescriptor; + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/SamlAttributeGenerator.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/SamlAttributeGenerator.java index cb4a4608..559a3959 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/SamlAttributeGenerator.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/SamlAttributeGenerator.java @@ -1,31 +1,26 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.builder; +import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeValue; import org.opensaml.xml.Configuration; @@ -35,58 +30,66 @@ import org.opensaml.xml.schema.XSString; import org.opensaml.xml.schema.impl.XSIntegerBuilder; import org.opensaml.xml.schema.impl.XSStringBuilder; -import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - public class SamlAttributeGenerator implements IAttributeGenerator<Attribute> { - - private XMLObject buildAttributeStringValue(String value) { - XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); - XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); - stringValue.setValue(value); - return stringValue; - } - - private XMLObject buildAttributeIntegerValue(int value) { - XSIntegerBuilder integerBuilder = (XSIntegerBuilder) Configuration.getBuilderFactory().getBuilder(XSInteger.TYPE_NAME); - XSInteger integerValue = integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME); - integerValue.setValue(value); - return integerValue; - } - - public Attribute buildStringAttribute(final String friendlyName, final String name, final String value) { - Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class); - attribute.setFriendlyName(friendlyName); - attribute.setName(name); - attribute.setNameFormat(Attribute.URI_REFERENCE); - attribute.getAttributeValues().add(buildAttributeStringValue(value)); - return attribute; - } - - public Attribute buildIntegerAttribute(final String friendlyName, final String name, final int value) { - Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class); - attribute.setFriendlyName(friendlyName); - attribute.setName(name); - attribute.setNameFormat(Attribute.URI_REFERENCE); - attribute.getAttributeValues().add(buildAttributeIntegerValue(value)); - return attribute; - } - - public Attribute buildEmptyAttribute(final String friendlyName, final String name) { - Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class); - attribute.setFriendlyName(friendlyName); - attribute.setName(name); - attribute.setNameFormat(Attribute.URI_REFERENCE); - return attribute; - } - public Attribute buildLongAttribute(String friendlyName, String name, long value) { - Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class); - attribute.setFriendlyName(friendlyName); - attribute.setName(name); - attribute.setNameFormat(Attribute.URI_REFERENCE); - attribute.getAttributeValues().add(buildAttributeIntegerValue((int) value)); - return attribute; - } - + private XMLObject buildAttributeStringValue(final String value) { + final XSStringBuilder stringBuilder = + (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); + final XSString stringValue = + stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); + stringValue.setValue(value); + return stringValue; + } + + private XMLObject buildAttributeIntegerValue(final int value) { + final XSIntegerBuilder integerBuilder = + (XSIntegerBuilder) Configuration.getBuilderFactory().getBuilder(XSInteger.TYPE_NAME); + final XSInteger integerValue = + integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME); + integerValue.setValue(value); + return integerValue; + } + + @Override + public Attribute buildStringAttribute(final String friendlyName, final String name, + final String value) { + final Attribute attribute = Saml2Utils.createSamlObject(Attribute.class); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.setNameFormat(Attribute.URI_REFERENCE); + attribute.getAttributeValues().add(buildAttributeStringValue(value)); + return attribute; + } + + @Override + public Attribute buildIntegerAttribute(final String friendlyName, final String name, + final int value) { + final Attribute attribute = Saml2Utils.createSamlObject(Attribute.class); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.setNameFormat(Attribute.URI_REFERENCE); + attribute.getAttributeValues().add(buildAttributeIntegerValue(value)); + return attribute; + } + + @Override + public Attribute buildEmptyAttribute(final String friendlyName, final String name) { + final Attribute attribute = Saml2Utils.createSamlObject(Attribute.class); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.setNameFormat(Attribute.URI_REFERENCE); + return attribute; + } + + @Override + public Attribute buildLongAttribute(final String friendlyName, final String name, + final long value) { + final Attribute attribute = Saml2Utils.createSamlObject(Attribute.class); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.setNameFormat(Attribute.URI_REFERENCE); + attribute.getAttributeValues().add(buildAttributeIntegerValue((int) value)); + return attribute; + } + } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFExtensionImplementation.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFExtensionImplementation.java deleted file mode 100644 index 817ca2f6..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFExtensionImplementation.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import org.opensaml.saml2.common.impl.ExtensionsImpl; - -public class EAAFExtensionImplementation extends ExtensionsImpl { - - protected EAAFExtensionImplementation(String namespaceURI, String elementLocalName, String namespacePrefix) { - super(namespaceURI, elementLocalName, namespacePrefix); - - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestExtensionBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestExtensionBuilder.java deleted file mode 100644 index 431784cf..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestExtensionBuilder.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import org.opensaml.common.impl.AbstractSAMLObjectBuilder; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.common.Extensions; - -public class EAAFRequestExtensionBuilder extends AbstractSAMLObjectBuilder<Extensions> { - - @Override - public Extensions buildObject() { - return buildObject(SAMLConstants.SAML20P_NS, Extensions.LOCAL_NAME, SAMLConstants.SAML20P_PREFIX); - - } - - @Override - public Extensions buildObject(String namespaceURI, String localName, String namespacePrefix) { - return new EAAFExtensionImplementation(namespaceURI, localName, namespacePrefix); - - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeBuilder.java deleted file mode 100644 index 33868544..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeBuilder.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import org.opensaml.common.impl.AbstractSAMLObjectBuilder; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; -import at.gv.egiz.eaaf.modules.pvp2.impl.reqattr.EAAFRequestedAttributeImpl; - -public class EAAFRequestedAttributeBuilder extends AbstractSAMLObjectBuilder<EAAFRequestedAttribute> { - - @Override - public EAAFRequestedAttribute buildObject() { - return buildObject(EAAFRequestedAttribute.DEFAULT_ELEMENT_NAME); - } - - @Override - public EAAFRequestedAttribute buildObject(String namespaceURI, String localName, String namespacePrefix) { - return new EAAFRequestedAttributeImpl(namespaceURI, localName, - namespacePrefix); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeMarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeMarshaller.java deleted file mode 100644 index d95adc8f..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeMarshaller.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import java.util.Map.Entry; - -import javax.xml.namespace.QName; - -import org.opensaml.Configuration; -import org.opensaml.common.impl.AbstractSAMLObjectMarshaller; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.io.MarshallingException; -import org.opensaml.xml.util.XMLHelper; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; - -public class EAAFRequestedAttributeMarshaller extends AbstractSAMLObjectMarshaller { - protected final void marshallAttributes(final XMLObject samlElement, - final Element domElement) throws MarshallingException { - final EAAFRequestedAttribute requestedAttr = (EAAFRequestedAttribute) samlElement; - - if (requestedAttr.getName() != null) { - domElement.setAttributeNS(null, EAAFRequestedAttribute.NAME_ATTRIB_NAME, requestedAttr.getName()); - } - - if (requestedAttr.getNameFormat() != null) { - domElement.setAttributeNS(null, EAAFRequestedAttribute.NAME_FORMAT_ATTR, requestedAttr.getNameFormat()); - } - - if (requestedAttr.getFriendlyName() != null) { - domElement.setAttributeNS(null, EAAFRequestedAttribute.FRIENDLY_NAME_ATT, requestedAttr.getFriendlyName()); - } - - if (requestedAttr.getIsRequiredXSBoolean() != null) { - domElement.setAttributeNS(null, EAAFRequestedAttribute.IS_REQUIRED_ATTR, requestedAttr.getIsRequiredXSBoolean()); - } - - Attr attr; - for (Entry<QName, String> entry : requestedAttr.getUnknownAttributes() - .entrySet()) { - attr = XMLHelper.constructAttribute(domElement.getOwnerDocument(), - entry.getKey()); - attr.setValue(entry.getValue()); - domElement.setAttributeNodeNS(attr); - if (Configuration.isIDAttribute(entry.getKey()) - || requestedAttr.getUnknownAttributes().isIDAttribute( - entry.getKey())) { - attr.getOwnerElement().setIdAttributeNode(attr, true); - } - } - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeUnmarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeUnmarshaller.java deleted file mode 100644 index a4515707..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributeUnmarshaller.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import javax.xml.namespace.QName; - -import org.opensaml.common.impl.AbstractSAMLObjectUnmarshaller; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.io.UnmarshallingException; -import org.opensaml.xml.util.XMLHelper; -import org.w3c.dom.Attr; - -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; - -public class EAAFRequestedAttributeUnmarshaller extends AbstractSAMLObjectUnmarshaller { - protected final void processChildElement(final XMLObject parentSAMLObject, final XMLObject childSAMLObject) throws UnmarshallingException { - final EAAFRequestedAttribute requestedAttr = (EAAFRequestedAttribute) parentSAMLObject; - final QName childQName = childSAMLObject.getElementQName(); - - if ("AttributeValue".equals(childQName.getLocalPart()) - && childQName.getNamespaceURI().equals(PVPConstants.EIDAT10_SAML_NS)) { - requestedAttr.getAttributeValues().add(childSAMLObject); - - } else - super.processChildElement(parentSAMLObject, childSAMLObject); - - } - - protected final void processAttribute(final XMLObject samlObject, final Attr attribute) throws UnmarshallingException { - final EAAFRequestedAttribute requestedAttr = (EAAFRequestedAttribute) samlObject; - if (attribute.getLocalName().equals(EAAFRequestedAttribute.NAME_ATTRIB_NAME)) { - requestedAttr.setName(attribute.getValue()); - - } else if (attribute.getLocalName().equals(EAAFRequestedAttribute.NAME_FORMAT_ATTR)) { - requestedAttr.setNameFormat(attribute.getValue()); - - } else if (attribute.getLocalName().equals(EAAFRequestedAttribute.FRIENDLY_NAME_ATT)) { - requestedAttr.setFriendlyName(attribute.getValue()); - - } else if (attribute.getLocalName().equals(EAAFRequestedAttribute.IS_REQUIRED_ATTR)) { - requestedAttr.setIsRequired(attribute.getValue()); - - } else { - final QName attribQName = XMLHelper.getNodeQName(attribute); - if (attribute.isId()) { - requestedAttr.getUnknownAttributes().registerID(attribQName); - } - requestedAttr.getUnknownAttributes().put(attribQName, - attribute.getValue()); - } - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesBuilder.java deleted file mode 100644 index 6e432b25..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesBuilder.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import org.opensaml.common.impl.AbstractSAMLObjectBuilder; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttributes; -import at.gv.egiz.eaaf.modules.pvp2.impl.reqattr.EAAFRequestedAttributesImpl; - -public class EAAFRequestedAttributesBuilder extends AbstractSAMLObjectBuilder<EAAFRequestedAttributes> { - - @Override - public EAAFRequestedAttributes buildObject() { - return buildObject(EAAFRequestedAttributes.DEFAULT_ELEMENT_NAME); - } - - @Override - public EAAFRequestedAttributes buildObject(String namespaceURI, String localName, String namespacePrefix) { - return new EAAFRequestedAttributesImpl(namespaceURI, localName, - namespacePrefix); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesMarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesMarshaller.java deleted file mode 100644 index 28d50422..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesMarshaller.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import org.opensaml.common.impl.AbstractSAMLObjectMarshaller; - -public class EAAFRequestedAttributesMarshaller extends AbstractSAMLObjectMarshaller { - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesUnmarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesUnmarshaller.java deleted file mode 100644 index b2758326..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EAAFRequestedAttributesUnmarshaller.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; - -import org.opensaml.common.impl.AbstractSAMLObjectUnmarshaller; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.io.UnmarshallingException; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttributes; - -public class EAAFRequestedAttributesUnmarshaller extends AbstractSAMLObjectUnmarshaller { - protected final void processChildElement(final XMLObject parentObject, - final XMLObject childObject) throws UnmarshallingException { - final EAAFRequestedAttributes attrStatement = (EAAFRequestedAttributes) parentObject; - if (childObject instanceof EAAFRequestedAttribute) { - attrStatement.getAttributes().add((EAAFRequestedAttribute) childObject); - - } else - super.processChildElement(parentObject, childObject); - - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafExtensionImplementation.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafExtensionImplementation.java new file mode 100644 index 00000000..e61f5e6e --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafExtensionImplementation.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import org.opensaml.saml2.common.impl.ExtensionsImpl; + +public class EaafExtensionImplementation extends ExtensionsImpl { + + protected EaafExtensionImplementation(final String namespaceUri, final String elementLocalName, + final String namespacePrefix) { + super(namespaceUri, elementLocalName, namespacePrefix); + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestExtensionBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestExtensionBuilder.java new file mode 100644 index 00000000..d8ea35a0 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestExtensionBuilder.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import org.opensaml.common.impl.AbstractSAMLObjectBuilder; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.common.Extensions; + +public class EaafRequestExtensionBuilder extends AbstractSAMLObjectBuilder<Extensions> { + + @Override + public Extensions buildObject() { + return buildObject(SAMLConstants.SAML20P_NS, Extensions.LOCAL_NAME, + SAMLConstants.SAML20P_PREFIX); + + } + + @Override + public Extensions buildObject(final String namespaceUri, final String localName, final String namespacePrefix) { + return new EaafExtensionImplementation(namespaceUri, localName, namespacePrefix); + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeBuilder.java new file mode 100644 index 00000000..4f91f267 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeBuilder.java @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.impl.reqattr.EaafRequestedAttributeImpl; +import org.opensaml.common.impl.AbstractSAMLObjectBuilder; + +public class EaafRequestedAttributeBuilder + extends AbstractSAMLObjectBuilder<EaafRequestedAttribute> { + + @Override + public EaafRequestedAttribute buildObject() { + return buildObject(EaafRequestedAttribute.DEFAULT_ELEMENT_NAME); + } + + @Override + public EaafRequestedAttribute buildObject(final String namespaceUri, final String localName, + final String namespacePrefix) { + return new EaafRequestedAttributeImpl(namespaceUri, localName, namespacePrefix); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeMarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeMarshaller.java new file mode 100644 index 00000000..a370818e --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeMarshaller.java @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import java.util.Map.Entry; +import javax.xml.namespace.QName; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import org.opensaml.common.impl.AbstractSAMLObjectMarshaller; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.util.XMLHelper; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; + +public class EaafRequestedAttributeMarshaller extends AbstractSAMLObjectMarshaller { + @Override + protected final void marshallAttributes(final XMLObject samlElement, final Element domElement) + throws MarshallingException { + final EaafRequestedAttribute requestedAttr = (EaafRequestedAttribute) samlElement; + + if (requestedAttr.getName() != null) { + domElement.setAttributeNS(null, EaafRequestedAttribute.NAME_ATTRIB_NAME, + requestedAttr.getName()); + } + + if (requestedAttr.getNameFormat() != null) { + domElement.setAttributeNS(null, EaafRequestedAttribute.NAME_FORMAT_ATTR, + requestedAttr.getNameFormat()); + } + + if (requestedAttr.getFriendlyName() != null) { + domElement.setAttributeNS(null, EaafRequestedAttribute.FRIENDLY_NAME_ATT, + requestedAttr.getFriendlyName()); + } + + if (requestedAttr.getIsRequiredXsBoolean() != null) { + domElement.setAttributeNS(null, EaafRequestedAttribute.IS_REQUIRED_ATTR, + requestedAttr.getIsRequiredXsBoolean()); + } + + Attr attr; + for (final Entry<QName, String> entry : requestedAttr.getUnknownAttributes().entrySet()) { + attr = XMLHelper.constructAttribute(domElement.getOwnerDocument(), entry.getKey()); + attr.setValue(entry.getValue()); + domElement.setAttributeNodeNS(attr); + if (org.opensaml.xml.Configuration.isIDAttribute(entry.getKey()) + || requestedAttr.getUnknownAttributes().isIDAttribute(entry.getKey())) { + attr.getOwnerElement().setIdAttributeNode(attr, true); + } + } + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeUnmarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeUnmarshaller.java new file mode 100644 index 00000000..25baed16 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributeUnmarshaller.java @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import javax.xml.namespace.QName; + +import org.opensaml.common.impl.AbstractSAMLObjectUnmarshaller; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.io.UnmarshallingException; +import org.opensaml.xml.util.XMLHelper; +import org.w3c.dom.Attr; + +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; + +public class EaafRequestedAttributeUnmarshaller extends AbstractSAMLObjectUnmarshaller { + @Override + protected final void processChildElement(final XMLObject parentSamlObject, + final XMLObject childSamlObject) throws UnmarshallingException { + final EaafRequestedAttribute requestedAttr = (EaafRequestedAttribute) parentSamlObject; + final QName childQName = childSamlObject.getElementQName(); + + if ("AttributeValue".equals(childQName.getLocalPart()) + && childQName.getNamespaceURI().equals(PvpConstants.EIDAT10_SAML_NS)) { + requestedAttr.getAttributeValues().add(childSamlObject); + + } else { + super.processChildElement(parentSamlObject, childSamlObject); + } + + } + + @Override + protected final void processAttribute(final XMLObject samlObject, final Attr attribute) + throws UnmarshallingException { + final EaafRequestedAttribute requestedAttr = (EaafRequestedAttribute) samlObject; + if (attribute.getLocalName().equals(EaafRequestedAttribute.NAME_ATTRIB_NAME)) { + requestedAttr.setName(attribute.getValue()); + + } else if (attribute.getLocalName().equals(EaafRequestedAttribute.NAME_FORMAT_ATTR)) { + requestedAttr.setNameFormat(attribute.getValue()); + + } else if (attribute.getLocalName().equals(EaafRequestedAttribute.FRIENDLY_NAME_ATT)) { + requestedAttr.setFriendlyName(attribute.getValue()); + + } else if (attribute.getLocalName().equals(EaafRequestedAttribute.IS_REQUIRED_ATTR)) { + requestedAttr.setIsRequired(attribute.getValue()); + + } else { + final QName attribQName = XMLHelper.getNodeQName(attribute); + if (attribute.isId()) { + requestedAttr.getUnknownAttributes().registerID(attribQName); + } + requestedAttr.getUnknownAttributes().put(attribQName, attribute.getValue()); + } + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesBuilder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesBuilder.java new file mode 100644 index 00000000..1f68747f --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesBuilder.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import org.opensaml.common.impl.AbstractSAMLObjectBuilder; + +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; +import at.gv.egiz.eaaf.modules.pvp2.impl.reqattr.EaafRequestedAttributesImpl; + +public class EaafRequestedAttributesBuilder + extends AbstractSAMLObjectBuilder<EaafRequestedAttributes> { + + @Override + public EaafRequestedAttributes buildObject() { + return buildObject(EaafRequestedAttributes.DEFAULT_ELEMENT_NAME); + } + + @Override + public EaafRequestedAttributes buildObject(final String namespaceUri, final String localName, + final String namespacePrefix) { + return new EaafRequestedAttributesImpl(namespaceUri, localName, namespacePrefix); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesMarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesMarshaller.java new file mode 100644 index 00000000..2fff64b3 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesMarshaller.java @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import org.opensaml.common.impl.AbstractSAMLObjectMarshaller; + +public class EaafRequestedAttributesMarshaller extends AbstractSAMLObjectMarshaller { + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesUnmarshaller.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesUnmarshaller.java new file mode 100644 index 00000000..b2cf7a82 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/builder/reqattr/EaafRequestedAttributesUnmarshaller.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr; + +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; +import org.opensaml.common.impl.AbstractSAMLObjectUnmarshaller; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.io.UnmarshallingException; + +public class EaafRequestedAttributesUnmarshaller extends AbstractSAMLObjectUnmarshaller { + @Override + protected final void processChildElement(final XMLObject parentObject, + final XMLObject childObject) throws UnmarshallingException { + final EaafRequestedAttributes attrStatement = (EaafRequestedAttributes) parentObject; + if (childObject instanceof EaafRequestedAttribute) { + attrStatement.getAttributes().add((EaafRequestedAttribute) childObject); + + } else { + super.processChildElement(parentObject, childObject); + } + + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java index 452fa553..107a856e 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java @@ -1,123 +1,135 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.message; import java.io.Serializable; - +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; -import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException; - -/** - * @author tlenz - * - */ -public class InboundMessage implements InboundMessageInterface, Serializable{ - private static final Logger log = LoggerFactory.getLogger(InboundMessage.class); - - private static final long serialVersionUID = 2395131650841669663L; - - private Element samlMessage = null; - private boolean verified = false; - private String entityID = null; - private String relayState = null; - - - public EntityDescriptor getEntityMetadata(IPVPMetadataProvider metadataProvider) throws NoMetadataInformationException { - try { - if (metadataProvider == null) - throw new NullPointerException("No PVP MetadataProvider found."); - - return metadataProvider.getEntityDescriptor(this.entityID); - - } catch (MetadataProviderException e) { - log.warn("No Metadata for EntitiyID " + entityID); - throw new NoMetadataInformationException(); - } - } - - /** - * @param entitiyID the entitiyID to set - */ - public void setEntityID(String entitiyID) { - this.entityID = entitiyID; - } - - public void setVerified(boolean verified) { - this.verified = verified; - } - - /** - * @param relayState the relayState to set - */ - public void setRelayState(String relayState) { - this.relayState = relayState; - } - - public void setSAMLMessage(Element msg) { - this.samlMessage = msg; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#getRelayState() - */ - @Override - public String getRelayState() { - return relayState; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#getEntityID() - */ - @Override - public String getEntityID() { - return entityID; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#isVerified() - */ - @Override - public boolean isVerified() { - return verified; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#getInboundMessage() - */ - @Override - public Element getInboundMessage() { - return samlMessage; - } +public class InboundMessage implements InboundMessageInterface, Serializable { + private static final Logger log = LoggerFactory.getLogger(InboundMessage.class); + + private static final long serialVersionUID = 2395131650841669663L; + + private Element samlMessage = null; + private boolean verified = false; + private String entityID = null; + private String relayState = null; + + /** + * Get SAML2 metadata for Entity that sends this request. + * + * @param metadataProvider Metadataprovider + * @return EntityDescriptor from metadata + * @throws NoMetadataInformationException In case of an error + */ + public EntityDescriptor getEntityMetadata(final IPvpMetadataProvider metadataProvider) + throws NoMetadataInformationException { + try { + if (metadataProvider == null) { + throw new NullPointerException("No PVP MetadataProvider found."); + } + + return metadataProvider.getEntityDescriptor(this.entityID); + + } catch (final MetadataProviderException e) { + log.warn("No Metadata for EntitiyID " + entityID); + throw new NoMetadataInformationException(); + } + } + + /** + * Set EntitId of requester. + * + * @param entitiyID the entitiyID to set + */ + public void setEntityID(final String entitiyID) { + this.entityID = entitiyID; + } + + public void setVerified(final boolean verified) { + this.verified = verified; + } + + /** + * Set relayState from requester. + * + * @param relayState the relayState to set + */ + public void setRelayState(final String relayState) { + this.relayState = relayState; + } + + /** + * Set full SAML2 message. + * + * @param msg message + */ + public void setSamlMessage(final Element msg) { + this.samlMessage = msg; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#getRelayState() + */ + @Override + public String getRelayState() { + return relayState; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#getEntityID() + */ + @Override + public String getEntityID() { + return entityID; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#isVerified() + */ + @Override + public boolean isVerified() { + return verified; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.messages.PVP21InboundMessage#getInboundMessage() + */ + @Override + public Element getInboundMessage() { + return samlMessage; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PVPSProfileRequest.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PVPSProfileRequest.java deleted file mode 100644 index 9c9c913d..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PVPSProfileRequest.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.message; - - -import org.opensaml.Configuration; -import org.opensaml.xml.io.Unmarshaller; -import org.opensaml.xml.io.UnmarshallerFactory; -import org.opensaml.xml.io.UnmarshallingException; -import org.opensaml.xml.signature.SignableXMLObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PVPSProfileRequest extends InboundMessage{ - private static final Logger log = LoggerFactory.getLogger(PVPSProfileRequest.class); - - private static final long serialVersionUID = 8613921176727607896L; - - private String binding = null; - - public PVPSProfileRequest(SignableXMLObject inboundMessage, String binding) { - setSAMLMessage(inboundMessage.getDOM()); - this.binding = binding; - - } - - public String getRequestBinding() { - return binding; - } - - public SignableXMLObject getSamlRequest() { - UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory(); - Unmarshaller unmashaller = unmarshallerFactory.getUnmarshaller(getInboundMessage()); - - try { - return (SignableXMLObject) unmashaller.unmarshall(getInboundMessage()); - - } catch (UnmarshallingException e) { - log.warn("AuthnRequest Unmarshaller error", e); - return null; - } - - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PVPSProfileResponse.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PVPSProfileResponse.java deleted file mode 100644 index 107aa731..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PVPSProfileResponse.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.message; - -import org.opensaml.Configuration; -import org.opensaml.saml2.core.StatusResponseType; -import org.opensaml.xml.io.Unmarshaller; -import org.opensaml.xml.io.UnmarshallerFactory; -import org.opensaml.xml.io.UnmarshallingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PVPSProfileResponse extends InboundMessage { - - private static final Logger log = LoggerFactory.getLogger(PVPSProfileResponse.class); - - private static final long serialVersionUID = -1133012928130138501L; - - public PVPSProfileResponse(StatusResponseType response) { - setSAMLMessage(response.getDOM()); - } - - public StatusResponseType getResponse() { - UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory(); - Unmarshaller unmashaller = unmarshallerFactory.getUnmarshaller(getInboundMessage()); - - try { - return (StatusResponseType) unmashaller.unmarshall(getInboundMessage()); - - } catch (UnmarshallingException e) { - log.warn("AuthnResponse Unmarshaller error", e); - return null; - } - - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PvpSProfileRequest.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PvpSProfileRequest.java new file mode 100644 index 00000000..dce2dd04 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PvpSProfileRequest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.message; + + +import org.opensaml.xml.io.Unmarshaller; +import org.opensaml.xml.io.UnmarshallerFactory; +import org.opensaml.xml.io.UnmarshallingException; +import org.opensaml.xml.signature.SignableXMLObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PvpSProfileRequest extends InboundMessage { + private static final Logger log = LoggerFactory.getLogger(PvpSProfileRequest.class); + + private static final long serialVersionUID = 8613921176727607896L; + + private String binding = null; + + /** + * PVP2 S-Profil request DAO. + * + * @param inboundMessage SAML2 request object + * @param binding Used SAML2 binding + */ + public PvpSProfileRequest(final SignableXMLObject inboundMessage, final String binding) { + setSamlMessage(inboundMessage.getDOM()); + this.binding = binding; + + } + + public String getRequestBinding() { + return binding; + } + + /** + * Get SAML2 request object. + * + * @return + */ + public SignableXMLObject getSamlRequest() { + final UnmarshallerFactory unmarshallerFactory = + org.opensaml.xml.Configuration.getUnmarshallerFactory(); + final Unmarshaller unmashaller = unmarshallerFactory.getUnmarshaller(getInboundMessage()); + + try { + return (SignableXMLObject) unmashaller.unmarshall(getInboundMessage()); + + } catch (final UnmarshallingException e) { + log.warn("AuthnRequest Unmarshaller error", e); + return null; + } + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PvpSProfileResponse.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PvpSProfileResponse.java new file mode 100644 index 00000000..8d1cbe8c --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/PvpSProfileResponse.java @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.message; + +import org.opensaml.saml2.core.StatusResponseType; +import org.opensaml.xml.io.Unmarshaller; +import org.opensaml.xml.io.UnmarshallerFactory; +import org.opensaml.xml.io.UnmarshallingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PvpSProfileResponse extends InboundMessage { + + private static final Logger log = LoggerFactory.getLogger(PvpSProfileResponse.class); + + private static final long serialVersionUID = -1133012928130138501L; + + public PvpSProfileResponse(final StatusResponseType response) { + setSamlMessage(response.getDOM()); + } + + /** + * Get SAML2 Response object. + * + * @return + */ + public StatusResponseType getResponse() { + final UnmarshallerFactory unmarshallerFactory = + org.opensaml.xml.Configuration.getUnmarshallerFactory(); + final Unmarshaller unmashaller = unmarshallerFactory.getUnmarshaller(getInboundMessage()); + + try { + return (StatusResponseType) unmashaller.unmarshall(getInboundMessage()); + + } catch (final UnmarshallingException e) { + log.warn("AuthnResponse Unmarshaller error", e); + return null; + } + + } + +} 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 08ef26ab..ec81353a 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 @@ -1,29 +1,22 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.metadata; import java.io.IOException; @@ -35,9 +28,12 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Timer; - import javax.xml.namespace.QName; - +import at.gv.egiz.components.spring.api.IDestroyableObject; +import at.gv.egiz.eaaf.core.api.IGarbageCollectorProcessing; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; import org.apache.commons.lang3.StringUtils; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; @@ -52,419 +48,474 @@ import org.opensaml.xml.XMLObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.components.spring.api.IDestroyableObject; -import at.gv.egiz.eaaf.core.api.IGarbageCollectorProcessing; -import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; - public abstract class AbstractChainingMetadataProvider extends SimpleMetadataProvider - implements ObservableMetadataProvider, IGarbageCollectorProcessing, - IRefreshableMetadataProvider, IDestroyableObject, IPVPMetadataProvider { - - private static final Logger log = LoggerFactory.getLogger(AbstractChainingMetadataProvider.class); - - private MetadataProvider internalProvider = null; - private static Object mutex = new Object(); - private Timer timer = null; - - - public AbstractChainingMetadataProvider() { - internalProvider = new ChainingMetadataProvider(); - - } - - public final Timer getTimer() { - return this.timer; - - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() - */ - @Override - public void runGarbageCollector() { - synchronized (mutex) { - /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ - try { - log.trace("Check consistence of PVP2X metadata"); - addAndRemoveMetadataProvider(); - - } catch (EAAFConfigurationException e) { - log.error("Access to MOA-ID configuration FAILED.", e); - - } - } - - } - - public void fullyDestroy() { - internalDestroy(); - - } - - @Override - public synchronized boolean refreshMetadataProvider(String entityID) { - try { - //check if metadata provider is already loaded - try { - if (internalProvider.getEntityDescriptor(entityID) != null) - return true; - - } catch (MetadataProviderException e) {} - - - //reload metadata provider - String metadataURL = getMetadataURL(entityID); - if (StringUtils.isNotEmpty(metadataURL)) { - Map<String, HTTPMetadataProvider> actuallyLoadedProviders = getAllActuallyLoadedProviders(); - - // check if MetadataProvider is actually loaded - if (actuallyLoadedProviders.containsKey(metadataURL)) { - actuallyLoadedProviders.get(metadataURL).refresh(); - log.info("SAML2 metadata for service provider: " - + entityID + " is refreshed."); - return true; - - } else { - //load new Metadata Provider - if (timer == null) - timer = new Timer(true); - - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - chainProvider.addMetadataProvider(createNewMetadataProvider(entityID)); - - emitChangeEvent(); - log.info("SAML2 metadata for service provider: " - + entityID + " is added."); - return true; - - } - - } else - log.debug("Can not refresh SAML2 metadata: NO SAML2 metadata URL for SP with Id: " + entityID); - - } catch (MetadataProviderException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } catch (IOException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } catch (EAAFConfigurationException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } catch (CertificateException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } - - return false; - - } - - public void internalDestroy() { - if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { - log.info("Destrorying PVP-Authentication MetaDataProvider."); - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - List<MetadataProvider> providers = chainProvider.getProviders(); - for (MetadataProvider provider : providers) { - if (provider instanceof HTTPMetadataProvider) { - HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; - log.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI()); - httpprovider.destroy(); - - } else { - log.warn("MetadataProvider can not be destroyed."); - } - } - - internalProvider = new ChainingMetadataProvider(); - - if (timer != null) - timer.cancel(); - - } else { - log.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); - } - } - - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#requireValidMetadata() - */ - @Override - public boolean requireValidMetadata() { - return internalProvider.requireValidMetadata(); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setRequireValidMetadata(boolean) - */ - @Override - public void setRequireValidMetadata(boolean requireValidMetadata) { - internalProvider.setRequireValidMetadata(requireValidMetadata); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadataFilter() - */ - @Override - public MetadataFilter getMetadataFilter() { - return internalProvider.getMetadataFilter(); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setMetadataFilter(org.opensaml.saml2.metadata.provider.MetadataFilter) - */ - @Override - public void setMetadataFilter(MetadataFilter newFilter) - throws MetadataProviderException { - internalProvider.setMetadataFilter(newFilter); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadata() - */ - @Override - public XMLObject getMetadata() throws MetadataProviderException { - return internalProvider.getMetadata(); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntitiesDescriptor(java.lang.String) - */ - @Override - public EntitiesDescriptor getEntitiesDescriptor(String entitiesID) - throws MetadataProviderException { - EntitiesDescriptor entitiesDesc = null; - try { - entitiesDesc = internalProvider.getEntitiesDescriptor(entitiesID); - - if (entitiesDesc == null) { - log.debug("Can not find PVP metadata for entityID: " + entitiesID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entitiesID)) - return internalProvider.getEntitiesDescriptor(entitiesID); - - } - - } catch (MetadataProviderException e) { - log.debug("Can not find PVP metadata for entityID: " + entitiesID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entitiesID)) - return internalProvider.getEntitiesDescriptor(entitiesID); - - } - - return entitiesDesc; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntityDescriptor(java.lang.String) - */ - @Override - public EntityDescriptor getEntityDescriptor(String entityID) - throws MetadataProviderException { - EntityDescriptor entityDesc = null; - try { - entityDesc = internalProvider.getEntityDescriptor(entityID); - if (entityDesc == null) { - log.debug("Can not find PVP metadata for entityID: " + entityID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entityID)) - return internalProvider.getEntityDescriptor(entityID); - - } - - } catch (MetadataProviderException e) { - log.debug("Can not find PVP metadata for entityID: " + entityID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entityID)) - return internalProvider.getEntityDescriptor(entityID); - - } - -// if (entityDesc != null) -// lastAccess.put(entityID, new Date()); - - return entityDesc; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang.String, javax.xml.namespace.QName) - */ - @Override - public List<RoleDescriptor> getRole(String entityID, QName roleName) - throws MetadataProviderException { - List<RoleDescriptor> result = internalProvider.getRole(entityID, roleName); - -// if (result != null) -// lastAccess.put(entityID, new Date()); - - return result; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang.String, javax.xml.namespace.QName, java.lang.String) - */ - @Override - public RoleDescriptor getRole(String entityID, QName roleName, - String supportedProtocol) throws MetadataProviderException { - RoleDescriptor result = internalProvider.getRole(entityID, roleName, supportedProtocol); - -// if (result != null) -// lastAccess.put(entityID, new Date()); - - return result; - } - - /* (non-Javadoc) - * @see org.opensaml.saml2.metadata.provider.ObservableMetadataProvider#getObservers() - */ - @Override - public List<Observer> getObservers() { - return ((ChainingMetadataProvider) internalProvider).getObservers(); - } - - - /** - * Get the URL to metadata for a specific entityID - * - * @param entityId - * @return - * @throws EAAFConfigurationException - */ - protected abstract String getMetadataURL(String entityId) throws EAAFConfigurationException; - - /** - * Creates a new implementation specific SAML2 metadata provider - * - * @param entityId - * @return - * @throws EAAFConfigurationException - * @throws IOException - * @throws CertificateException - * @throws ConfigurationException - */ - protected abstract MetadataProvider createNewMetadataProvider(String entityId) throws EAAFConfigurationException, IOException, CertificateException; - - /** - * Get a List of metadata URLs for all SAML2 SPs from configuration - * - * @throws EAAFConfigurationException - */ - protected abstract List<String> getAllMetadataURLsFromConfiguration() throws EAAFConfigurationException; - - - protected void emitChangeEvent() { - if ((getObservers() == null) || (getObservers().size() == 0)) { - return; - } - - List<Observer> tempObserverList = new ArrayList<Observer>(getObservers()); - for (ObservableMetadataProvider.Observer observer : tempObserverList) - if (observer != null) - observer.onEvent(this); - } - - private Map<String, HTTPMetadataProvider> getAllActuallyLoadedProviders() { - Map<String, HTTPMetadataProvider> loadedproviders = new HashMap<String, HTTPMetadataProvider>(); - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - //make a Map of all actually loaded HTTPMetadataProvider - List<MetadataProvider> providers = chainProvider.getProviders(); - for (MetadataProvider provider : providers) { - if (provider instanceof HTTPMetadataProvider) { - HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; - loadedproviders.put(httpprovider.getMetadataURI(), httpprovider); - - } - } - - return loadedproviders; - } - - private void addAndRemoveMetadataProvider() throws EAAFConfigurationException { - if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { - log.info("Reload MOAMetaDataProvider."); - - /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) - *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ - Map<String, MetadataProvider> providersinuse = new HashMap<String, MetadataProvider>(); - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - //get all actually loaded metadata providers - Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); - - /* TODO: maybe add metadata provider destroy after timeout. - * But could be a problem if one Metadataprovider load an EntitiesDescriptor - * with more the multiple EntityDescriptors. If one of this EntityDesciptors - * are expired the full EntitiesDescriptor is removed. - * - * Timeout requires a better solution in this case! - */ - - //load all SAML2 SPs form configuration and - //compare actually loaded Providers with configured SAML2 SPs - List<String> allMetadataURLs = getAllMetadataURLsFromConfiguration(); - - if (allMetadataURLs != null) { - Iterator<String> metadataURLInterator = allMetadataURLs.iterator(); - while (metadataURLInterator.hasNext()) { - String metadataurl = metadataURLInterator.next(); - try { - if (StringUtils.isNotEmpty(metadataurl)) { - if (loadedproviders.containsKey(metadataurl)) { - // SAML2 SP is actually loaded, to nothing - providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); - loadedproviders.remove(metadataurl); - - } - } - } catch (Throwable e) { - log.error( - "Failed to add Metadata (unhandled reason: " + e.getMessage(), e); - - } - } - } - - //remove all actually loaded MetadataProviders with are not in ConfigurationDB any more - Collection<HTTPMetadataProvider> notusedproviders = loadedproviders.values(); - for (HTTPMetadataProvider provider : notusedproviders) { - String metadataurl = provider.getMetadataURI(); - try { - provider.destroy(); - - /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) - *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ - //chainProvider.removeMetadataProvider(provider); - log.info("Remove not used MetadataProvider with MetadataURL " + metadataurl); - - } catch (Throwable e) { - log.error("HTTPMetadataProvider with URL " + metadataurl - + " can not be removed from the list of actually loaded Providers.", e); - - } - - } - - try { - chainProvider.setProviders(new ArrayList<MetadataProvider>(providersinuse.values())); - emitChangeEvent(); - - } catch (MetadataProviderException e) { - log.warn("ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy", e); - - } - - } else - log.warn("ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy"); - - } + implements ObservableMetadataProvider, IGarbageCollectorProcessing, + IRefreshableMetadataProvider, IDestroyableObject, IPvpMetadataProvider { + + private static final Logger log = LoggerFactory.getLogger(AbstractChainingMetadataProvider.class); + + private MetadataProvider internalProvider = null; + private static Object mutex = new Object(); + private Timer timer = null; + + + public AbstractChainingMetadataProvider() { + internalProvider = new ChainingMetadataProvider(); + + } + + public final Timer getTimer() { + return this.timer; + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() + */ + @Override + public void runGarbageCollector() { + synchronized (mutex) { + /* add new Metadataprovider or remove Metadataprovider which are not in use any more. */ + try { + log.trace("Check consistence of PVP2X metadata"); + addAndRemoveMetadataProvider(); + + } catch (final EaafConfigurationException e) { + log.error("Access to MOA-ID configuration FAILED.", e); + + } + } + + } + + @Override + public void fullyDestroy() { + internalDestroy(); + + } + + @Override + public synchronized boolean refreshMetadataProvider(final String entityID) { + try { + // check if metadata provider is already loaded + try { + if (internalProvider.getEntityDescriptor(entityID) != null) { + return true; + } + + } catch (final MetadataProviderException e) { + log.debug("Metadata for EntityId: {} is not valid. Starting refresh ... ", entityID); + + } + + + // reload metadata provider + final String metadataUrl = getMetadataUrl(entityID); + if (StringUtils.isNotEmpty(metadataUrl)) { + final Map<String, HTTPMetadataProvider> actuallyLoadedProviders = + getAllActuallyLoadedProviders(); + + // check if MetadataProvider is actually loaded + if (actuallyLoadedProviders.containsKey(metadataUrl)) { + actuallyLoadedProviders.get(metadataUrl).refresh(); + log.info("SAML2 metadata for service provider: " + entityID + " is refreshed."); + return true; + + } else { + // load new Metadata Provider + if (timer == null) { + timer = new Timer(true); + } + + final ChainingMetadataProvider chainProvider = + (ChainingMetadataProvider) internalProvider; + chainProvider.addMetadataProvider(createNewMetadataProvider(entityID)); + + emitChangeEvent(); + log.info("SAML2 metadata for service provider: " + entityID + " is added."); + return true; + + } + + } else { + log.debug( + "Can not refresh SAML2 metadata: NO SAML2 metadata URL for SP with Id: " + entityID); + } + + } catch (final MetadataProviderException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } catch (final IOException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } catch (final EaafConfigurationException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } catch (final CertificateException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } + + return false; + + } + + /** + * Close metadata provider and remove all loaded metadata. + * + */ + public void internalDestroy() { + if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { + log.info("Destrorying PVP-Authentication MetaDataProvider."); + final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + final List<MetadataProvider> providers = chainProvider.getProviders(); + for (final MetadataProvider provider : providers) { + if (provider instanceof HTTPMetadataProvider) { + final HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; + log.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI()); + httpprovider.destroy(); + + } else { + log.warn("MetadataProvider can not be destroyed."); + } + } + + internalProvider = new ChainingMetadataProvider(); + + if (timer != null) { + timer.cancel(); + } + + } else { + log.warn( + "ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); + } + } + + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#requireValidMetadata() + */ + @Override + public boolean requireValidMetadata() { + return internalProvider.requireValidMetadata(); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setRequireValidMetadata + * (boolean) + */ + @Override + public void setRequireValidMetadata(final boolean requireValidMetadata) { + internalProvider.setRequireValidMetadata(requireValidMetadata); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadataFilter() + */ + @Override + public MetadataFilter getMetadataFilter() { + return internalProvider.getMetadataFilter(); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setMetadataFilter(org. + * opensaml.saml2.metadata.provider.MetadataFilter) + */ + @Override + public void setMetadataFilter(final MetadataFilter newFilter) throws MetadataProviderException { + internalProvider.setMetadataFilter(newFilter); + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadata() + */ + @Override + public XMLObject getMetadata() throws MetadataProviderException { + return internalProvider.getMetadata(); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntitiesDescriptor( + * java.lang.String) + */ + @Override + public EntitiesDescriptor getEntitiesDescriptor(final String entitiesID) + throws MetadataProviderException { + EntitiesDescriptor entitiesDesc = null; + try { + entitiesDesc = internalProvider.getEntitiesDescriptor(entitiesID); + + if (entitiesDesc == null) { + log.debug("Can not find PVP metadata for entityID: " + entitiesID + + " Start refreshing process ..."); + if (refreshMetadataProvider(entitiesID)) { + return internalProvider.getEntitiesDescriptor(entitiesID); + } + + } + + } catch (final MetadataProviderException e) { + log.debug("Can not find PVP metadata for entityID: " + entitiesID + + " Start refreshing process ..."); + if (refreshMetadataProvider(entitiesID)) { + return internalProvider.getEntitiesDescriptor(entitiesID); + } + + } + + return entitiesDesc; + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntityDescriptor( + * java.lang.String) + */ + @Override + public EntityDescriptor getEntityDescriptor(final String entityID) + throws MetadataProviderException { + EntityDescriptor entityDesc = null; + try { + entityDesc = internalProvider.getEntityDescriptor(entityID); + if (entityDesc == null) { + log.debug("Can not find PVP metadata for entityID: " + entityID + + " Start refreshing process ..."); + if (refreshMetadataProvider(entityID)) { + return internalProvider.getEntityDescriptor(entityID); + } + + } + + } catch (final MetadataProviderException e) { + log.debug( + "Can not find PVP metadata for entityID: " + entityID + " Start refreshing process ..."); + if (refreshMetadataProvider(entityID)) { + return internalProvider.getEntityDescriptor(entityID); + } + + } + + // if (entityDesc != null) + // lastAccess.put(entityID, new Date()); + + return entityDesc; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang. + * String, javax.xml.namespace.QName) + */ + @Override + public List<RoleDescriptor> getRole(final String entityID, final QName roleName) + throws MetadataProviderException { + final List<RoleDescriptor> result = internalProvider.getRole(entityID, roleName); + + // if (result != null) + // lastAccess.put(entityID, new Date()); + + return result; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang. + * String, javax.xml.namespace.QName, java.lang.String) + */ + @Override + public RoleDescriptor getRole(final String entityID, final QName roleName, + final String supportedProtocol) throws MetadataProviderException { + final RoleDescriptor result = internalProvider.getRole(entityID, roleName, supportedProtocol); + + // if (result != null) + // lastAccess.put(entityID, new Date()); + + return result; + } + + /* + * (non-Javadoc) + * + * @see org.opensaml.saml2.metadata.provider.ObservableMetadataProvider#getObservers() + */ + @Override + public List<Observer> getObservers() { + return ((ChainingMetadataProvider) internalProvider).getObservers(); + } + + + /** + * Get the URL to metadata for a specific entityID. + * + * @param entityId EntityId + * @return URL to metadata + * @throws EaafConfigurationException In case of an error + */ + protected abstract String getMetadataUrl(String entityId) throws EaafConfigurationException; + + /** + * Creates a new implementation specific SAML2 metadata provider. + * + * @param entityId EntityId + * @return MetadataProvider + * @throws EaafConfigurationException In case of an error + * @throws IOException In case of an error + * @throws CertificateException In case of an error + * @throws ConfigurationException In case of an error + */ + protected abstract MetadataProvider createNewMetadataProvider(String entityId) + throws EaafConfigurationException, IOException, CertificateException; + + /** + * Get a List of metadata URLs for all SAML2 SPs from configuration. + * + * @throws EaafConfigurationException In case of an error + */ + protected abstract List<String> getAllMetadataUrlsFromConfiguration() + throws EaafConfigurationException; + + + protected void emitChangeEvent() { + if ((getObservers() == null) || (getObservers().size() == 0)) { + return; + } + + final List<Observer> tempObserverList = new ArrayList<>(getObservers()); + for (final ObservableMetadataProvider.Observer observer : tempObserverList) { + if (observer != null) { + observer.onEvent(this); + } + } + } + + private Map<String, HTTPMetadataProvider> getAllActuallyLoadedProviders() { + final Map<String, HTTPMetadataProvider> loadedproviders = + new HashMap<>(); + final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + // make a Map of all actually loaded HTTPMetadataProvider + final List<MetadataProvider> providers = chainProvider.getProviders(); + for (final MetadataProvider provider : providers) { + if (provider instanceof HTTPMetadataProvider) { + final HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; + loadedproviders.put(httpprovider.getMetadataURI(), httpprovider); + + } + } + + return loadedproviders; + } + + private void addAndRemoveMetadataProvider() throws EaafConfigurationException { + if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { + log.info("Reload MOAMetaDataProvider."); + + /* + * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider + * (UnsupportedOperationException) The ChainingMetadataProvider use internal a + * unmodifiableList to hold all registrated MetadataProviders. + */ + final Map<String, MetadataProvider> providersinuse = new HashMap<>(); + final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + // get all actually loaded metadata providers + final Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); + + /* + * TODO: maybe add metadata provider destroy after timeout. But could be a problem if one + * Metadataprovider load an EntitiesDescriptor with more the multiple EntityDescriptors. If + * one of this EntityDesciptors are expired the full EntitiesDescriptor is removed. + * + * Timeout requires a better solution in this case! + */ + + // load all SAML2 SPs form configuration and + // compare actually loaded Providers with configured SAML2 SPs + final List<String> allMetadataUrls = getAllMetadataUrlsFromConfiguration(); + + if (allMetadataUrls != null) { + final Iterator<String> metadataUrlInterator = allMetadataUrls.iterator(); + while (metadataUrlInterator.hasNext()) { + final String metadataurl = metadataUrlInterator.next(); + try { + if (StringUtils.isNotEmpty(metadataurl)) { + if (loadedproviders.containsKey(metadataurl)) { + // SAML2 SP is actually loaded, to nothing + providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); + loadedproviders.remove(metadataurl); + + } + } + } catch (final Throwable e) { + log.error("Failed to add Metadata (unhandled reason: " + e.getMessage(), e); + + } + } + } + + // remove all actually loaded MetadataProviders with are not in ConfigurationDB any more + final Collection<HTTPMetadataProvider> notusedproviders = loadedproviders.values(); + for (final HTTPMetadataProvider provider : notusedproviders) { + final String metadataurl = provider.getMetadataURI(); + try { + provider.destroy(); + + /* + * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider + * (UnsupportedOperationException) The ChainingMetadataProvider use internal a + * unmodifiableList to hold all registrated MetadataProviders. + */ + // chainProvider.removeMetadataProvider(provider); + log.info("Remove not used MetadataProvider with MetadataURL " + metadataurl); + + } catch (final Throwable e) { + log.error("HTTPMetadataProvider with URL " + metadataurl + + " can not be removed from the list of actually loaded Providers.", e); + + } + + } + + try { + chainProvider.setProviders(new ArrayList<>(providersinuse.values())); + emitChangeEvent(); + + } catch (final MetadataProviderException e) { + log.warn( + "ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy", + e); + + } + + } else { + log.warn( + "ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy"); + } + + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/MetadataFilterChain.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/MetadataFilterChain.java index 06065a82..04c1dcb8 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/MetadataFilterChain.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/MetadataFilterChain.java @@ -1,34 +1,26 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.metadata; import java.util.ArrayList; import java.util.List; - import org.opensaml.saml2.metadata.provider.FilterException; import org.opensaml.saml2.metadata.provider.MetadataFilter; import org.opensaml.xml.XMLObject; @@ -37,44 +29,48 @@ import org.slf4j.LoggerFactory; /** + * Metadata filter-chain implementation. + * * @author tlenz * */ public class MetadataFilterChain implements MetadataFilter { - private static final Logger log = LoggerFactory.getLogger(MetadataFilterChain.class); - - - private List<MetadataFilter> filters = new ArrayList<MetadataFilter>(); - - /** - * Return all actually used Metadata filters - * - * @return List of Metadata filters - */ - public List<MetadataFilter> getFilters() { - return filters; - } - - /** - * Add a new Metadata filter to filterchain - * - * @param filter - */ - public void addFilter(MetadataFilter filter) { - filters.add(filter); - } - - - /* (non-Javadoc) - * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) - */ - @Override - public void doFilter(XMLObject arg0) throws FilterException { - for (MetadataFilter filter : filters) { - log.trace("Use EAAFMetadataFilter " + filter.getClass().getName()); - filter.doFilter(arg0); - } + private static final Logger log = LoggerFactory.getLogger(MetadataFilterChain.class); + + + private final List<MetadataFilter> filters = new ArrayList<>(); + + /** + * Return all actually used Metadata filters. + * + * @return List of Metadata filters + */ + public List<MetadataFilter> getFilters() { + return filters; + } + + /** + * Add a new Metadata filter to filterchain. + * + * @param filter add a metadata filter + */ + public void addFilter(final MetadataFilter filter) { + filters.add(filter); + } + + + /* + * (non-Javadoc) + * + * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) + */ + @Override + public void doFilter(final XMLObject arg0) throws FilterException { + for (final MetadataFilter filter : filters) { + log.trace("Use EAAFMetadataFilter " + filter.getClass().getName()); + filter.doFilter(arg0); + } - } + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/SimpleMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/SimpleMetadataProvider.java index c16ca5fd..67dd1d35 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/SimpleMetadataProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/SimpleMetadataProvider.java @@ -1,37 +1,32 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.metadata; import java.io.File; import java.net.MalformedURLException; import java.util.Timer; - import javax.net.ssl.SSLHandshakeException; - +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SignatureValidationException; import org.apache.commons.httpclient.HttpClient; import org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; @@ -42,195 +37,193 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.impl.utils.FileUtils; -import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SignatureValidationException; - /** + * Simple SAML2 metadata provider. + * * @author tlenz * */ -public abstract class SimpleMetadataProvider implements MetadataProvider{ - private static final Logger log = LoggerFactory.getLogger(SimpleMetadataProvider.class); - - private static final String URI_PREFIX_HTTP = "http:"; - private static final String URI_PREFIX_HTTPS = "https:"; - private static final String URI_PREFIX_FILE = "file:"; - - - @Autowired - protected IConfiguration authConfig; - - - /** - * Create a single SAML2 metadata provider - * - * @param metadataLocation where the metadata should be loaded, but never null. If the location starts with http(s):, than a http - * based metadata provider is used. If the location starts with file:, than a filesystem based metadata provider is used - * @param filter Filters, which should be used to validate the metadata - * @param IdForLogging Id, which is used for Logging - * @param timer {@link Timer} which is used to schedule metadata refresh operations - * @param httpClient Apache commons 3.x http client - * - * @return SAML2 Metadata Provider, or null if the metadata provider can not initialized - */ - protected MetadataProvider createNewSimpleMetadataProvider(String metadataLocation, MetadataFilter filter, - String IdForLogging, Timer timer, ParserPool pool, HttpClient httpClient) { - if (metadataLocation.startsWith(URI_PREFIX_HTTP) || metadataLocation.startsWith(URI_PREFIX_HTTPS)) { - if (httpClient != null) - return createNewHTTPMetaDataProvider(metadataLocation, filter, IdForLogging, timer, pool, httpClient); - - else { - log.warn("Can not load http(s) based SAML2 metadata without a HTTP client"); - return null; - } - - } else { - String absoluteMetadataLocation; - try { - absoluteMetadataLocation = FileUtils.makeAbsoluteURL( - metadataLocation, - authConfig.getConfigurationRootDirectory()); - - if (absoluteMetadataLocation.startsWith(URI_PREFIX_FILE)) { - File metadataFile = new File(absoluteMetadataLocation); - if (metadataFile.exists()) - return createNewFileSystemMetaDataProvider(metadataFile, filter, IdForLogging, timer, pool); - - else { - log.warn("SAML2 metadata file: " + absoluteMetadataLocation + " not found or not exist"); - return null; - } - - } - - - } catch (MalformedURLException e) { - log.warn("SAML2 metadata URL is invalid: " + metadataLocation, e); - - } - - } - - log.warn("SAML2 metadata has an unsupported metadata location prefix: " + metadataLocation); - return null; - - } - - - /** - * Create a single SAML2 filesystem based metadata provider - * - * @param metadataFile File, where the metadata should be loaded - * @param filter Filters, which should be used to validate the metadata - * @param IdForLogging Id, which is used for Logging - * @param timer {@link Timer} which is used to schedule metadata refresh operations - * @param pool - * - * @return SAML2 Metadata Provider - */ - private MetadataProvider createNewFileSystemMetaDataProvider(File metadataFile, MetadataFilter filter, String IdForLogging, Timer timer, ParserPool pool) { - FilesystemMetadataProvider fileSystemProvider = null; - try { - fileSystemProvider = new FilesystemMetadataProvider(timer, metadataFile); - fileSystemProvider.setParserPool(pool); - fileSystemProvider.setRequireValidMetadata(true); - fileSystemProvider.setMinRefreshDelay(1000*60*15); //15 minutes - fileSystemProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours - //httpProvider.setRefreshDelayFactor(0.1F); - - fileSystemProvider.setMetadataFilter(filter); - fileSystemProvider.initialize(); - - fileSystemProvider.setRequireValidMetadata(true); - - return fileSystemProvider; - - } catch (Exception e) { - log.warn( - "Failed to load Metadata file for " - + IdForLogging + "[ " - + "File: " + metadataFile.getAbsolutePath() - + " Msg: " + e.getMessage() + " ]", e); - - - log.warn("Can not initialize SAML2 metadata provider from filesystem: " + metadataFile.getAbsolutePath() - + " Reason: " + e.getMessage(), e); - - if (fileSystemProvider != null) - fileSystemProvider.destroy(); - - } - - return null; - - } - - - - /** - * Create a single SAML2 HTTP metadata provider - * - * @param metadataURL URL, where the metadata should be loaded - * @param filter Filters, which should be used to validate the metadata - * @param IdForLogging Id, which is used for Logging - * @param timer {@link Timer} which is used to schedule metadata refresh operations - * @param pool - * - * @return SAML2 Metadata Provider - */ - private MetadataProvider createNewHTTPMetaDataProvider(String metadataURL, MetadataFilter filter, String IdForLogging, Timer timer, ParserPool pool, HttpClient httpClient) { - HTTPMetadataProvider httpProvider = null; - try { - httpProvider = new HTTPMetadataProvider(timer, httpClient, - metadataURL); - httpProvider.setParserPool(pool); - httpProvider.setRequireValidMetadata(true); - httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes - httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours - //httpProvider.setRefreshDelayFactor(0.1F); - - httpProvider.setMetadataFilter(filter); - httpProvider.initialize(); - - httpProvider.setRequireValidMetadata(true); - - return httpProvider; - - } catch (Throwable e) { - if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) { - log.warn("SSL-Server certificate for metadata " - + metadataURL + " not trusted.", e); - - } if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) { - log.warn("Signature verification for metadata" - + metadataURL + " FAILED.", e); - - } if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) { - log.warn("Schema validation for metadata " - + metadataURL + " FAILED.", e); - } - - log.warn( - "Failed to load Metadata file for " - + IdForLogging + "[ " - + e.getMessage() + " ]", e); - - if (httpProvider != null) { - log.debug("Destroy failed Metadata provider"); - httpProvider.destroy(); - } - -// if (timer != null) { -// log.debug("Destroy Timer."); -// timer.cancel(); -// } - - - } - - return null; - } +public abstract class SimpleMetadataProvider implements MetadataProvider { + private static final Logger log = LoggerFactory.getLogger(SimpleMetadataProvider.class); + + private static final String URI_PREFIX_HTTP = "http:"; + private static final String URI_PREFIX_HTTPS = "https:"; + private static final String URI_PREFIX_FILE = "file:"; + + + @Autowired + protected IConfiguration authConfig; + + + /** + * Create a single SAML2 metadata provider. + * + * @param metadataLocation where the metadata should be loaded, but never null. If the location + * starts with http(s):, than a http based metadata provider is used. If the location + * starts with file:, than a filesystem based metadata provider is used + * @param filter Filters, which should be used to validate the metadata + * @param idForLogging Id, which is used for Logging + * @param timer {@link Timer} which is used to schedule metadata refresh operations + * @param httpClient Apache commons 3.x http client + * + * @return SAML2 Metadata Provider, or null if the metadata provider can not initialized + */ + protected MetadataProvider createNewSimpleMetadataProvider(final String metadataLocation, + final MetadataFilter filter, final String idForLogging, final Timer timer, + final ParserPool pool, final HttpClient httpClient) { + if (metadataLocation.startsWith(URI_PREFIX_HTTP) + || metadataLocation.startsWith(URI_PREFIX_HTTPS)) { + if (httpClient != null) { + return createNewHttpMetaDataProvider(metadataLocation, filter, idForLogging, timer, pool, + httpClient); + } else { + log.warn("Can not load http(s) based SAML2 metadata without a HTTP client"); + return null; + } + + } else { + String absoluteMetadataLocation; + try { + absoluteMetadataLocation = + FileUtils.makeAbsoluteUrl(metadataLocation, authConfig.getConfigurationRootDirectory()); + + if (absoluteMetadataLocation.startsWith(URI_PREFIX_FILE)) { + final File metadataFile = new File(absoluteMetadataLocation); + if (metadataFile.exists()) { + return createNewFileSystemMetaDataProvider(metadataFile, filter, idForLogging, timer, + pool); + } else { + log.warn( + "SAML2 metadata file: " + absoluteMetadataLocation + " not found or not exist"); + return null; + } + + } + + + } catch (final MalformedURLException e) { + log.warn("SAML2 metadata URL is invalid: " + metadataLocation, e); + + } + + } + + log.warn("SAML2 metadata has an unsupported metadata location prefix: " + metadataLocation); + return null; + + } + + + /** + * Create a single SAML2 filesystem based metadata provider. + * + * @param metadataFile File, where the metadata should be loaded + * @param filter Filters, which should be used to validate the metadata + * @param idForLogging Id, which is used for Logging + * @param timer {@link Timer} which is used to schedule metadata refresh operations + * @param pool + * + * @return SAML2 Metadata Provider + */ + private MetadataProvider createNewFileSystemMetaDataProvider(final File metadataFile, + final MetadataFilter filter, final String idForLogging, final Timer timer, + final ParserPool pool) { + FilesystemMetadataProvider fileSystemProvider = null; + try { + fileSystemProvider = new FilesystemMetadataProvider(timer, metadataFile); + fileSystemProvider.setParserPool(pool); + fileSystemProvider.setRequireValidMetadata(true); + fileSystemProvider.setMinRefreshDelay(1000 * 60 * 15); // 15 minutes + fileSystemProvider.setMaxRefreshDelay(1000 * 60 * 60 * 24); // 24 hours + // httpProvider.setRefreshDelayFactor(0.1F); + + fileSystemProvider.setMetadataFilter(filter); + fileSystemProvider.initialize(); + + fileSystemProvider.setRequireValidMetadata(true); + + return fileSystemProvider; + + } catch (final Exception e) { + log.warn("Failed to load Metadata file for " + idForLogging + "[ " + "File: " + + metadataFile.getAbsolutePath() + " Msg: " + e.getMessage() + " ]", e); + + + log.warn("Can not initialize SAML2 metadata provider from filesystem: " + + metadataFile.getAbsolutePath() + " Reason: " + e.getMessage(), e); + + if (fileSystemProvider != null) { + fileSystemProvider.destroy(); + } + + } + + return null; + + } + + + + /** + * Create a single SAML2 HTTP metadata provider. + * + * @param metadataUrl URL, where the metadata should be loaded + * @param filter Filters, which should be used to validate the metadata + * @param idForLogging Id, which is used for Logging + * @param timer {@link Timer} which is used to schedule metadata refresh operations + * @param pool + * + * @return SAML2 Metadata Provider + */ + private MetadataProvider createNewHttpMetaDataProvider(final String metadataUrl, + final MetadataFilter filter, final String idForLogging, final Timer timer, + final ParserPool pool, final HttpClient httpClient) { + HTTPMetadataProvider httpProvider = null; + try { + httpProvider = new HTTPMetadataProvider(timer, httpClient, metadataUrl); + httpProvider.setParserPool(pool); + httpProvider.setRequireValidMetadata(true); + httpProvider.setMinRefreshDelay(1000 * 60 * 15); // 15 minutes + httpProvider.setMaxRefreshDelay(1000 * 60 * 60 * 24); // 24 hours + // httpProvider.setRefreshDelayFactor(0.1F); + + httpProvider.setMetadataFilter(filter); + httpProvider.initialize(); + + httpProvider.setRequireValidMetadata(true); + + return httpProvider; + + } catch (final Throwable e) { + if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) { + log.warn("SSL-Server certificate for metadata " + metadataUrl + " not trusted.", e); + + } + if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) { + log.warn("Signature verification for metadata" + metadataUrl + " FAILED.", e); + + } + if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) { + log.warn("Schema validation for metadata " + metadataUrl + " FAILED.", e); + } + + log.warn("Failed to load Metadata file for " + idForLogging + "[ " + e.getMessage() + " ]", + e); + + if (httpProvider != null) { + log.debug("Destroy failed Metadata provider"); + httpProvider.destroy(); + } + + // if (timer != null) { + // log.debug("Destroy Timer."); + // timer.cancel(); + // } + + + } + + return null; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HTTPPostEncoderWithOwnTemplate.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HTTPPostEncoderWithOwnTemplate.java deleted file mode 100644 index 8af12acc..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HTTPPostEncoderWithOwnTemplate.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Writer; - -import org.apache.velocity.VelocityContext; -import org.apache.velocity.app.VelocityEngine; -import org.opensaml.common.binding.SAMLMessageContext; -import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; -import org.opensaml.ws.message.encoder.MessageEncodingException; -import org.opensaml.ws.transport.http.HTTPOutTransport; -import org.opensaml.ws.transport.http.HTTPTransportUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.eaaf.core.api.gui.IVelocityGUIBuilderConfiguration; -import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiFormBuilder; - -/** - * @author tlenz - * - */ -public class HTTPPostEncoderWithOwnTemplate extends HTTPPostEncoder { - private static final Logger log = LoggerFactory.getLogger(HTTPPostEncoderWithOwnTemplate.class); - - - private final VelocityEngine velocityEngine; - private final IVelocityGUIBuilderConfiguration guiConfig; - private final IVelocityGuiFormBuilder guiBuilder; - - /** - * @param engine - * @param templateId - */ - public HTTPPostEncoderWithOwnTemplate(IVelocityGUIBuilderConfiguration guiConfig, IVelocityGuiFormBuilder guiBuilder, VelocityEngine engine) { - super(engine, null); - this.velocityEngine = engine; - this.guiConfig = guiConfig; - this.guiBuilder = guiBuilder; - - } - - /** - * Base64 and POST encodes the outbound message and writes it to the outbound transport. - * - * @param messageContext current message context - * @param endpointURL endpoint URL to which to encode message - * - * @throws MessageEncodingException thrown if there is a problem encoding the message - */ - @Override - protected void postEncode(SAMLMessageContext messageContext, String endpointURL) throws MessageEncodingException { - log.debug("Invoking Velocity template to create POST body"); - InputStream is = null; - try { - //build Velocity Context from GUI input paramters - final VelocityContext context = guiBuilder.generateVelocityContextFromConfiguration(guiConfig); - - //load template - is = guiBuilder.getTemplateInputStream(guiConfig); - - //populate velocity context with SAML2 parameters - populateVelocityContext(context, messageContext, endpointURL); - - //populate transport parameter - final HTTPOutTransport outTransport = (HTTPOutTransport) messageContext.getOutboundMessageTransport(); - HTTPTransportUtils.addNoCacheHeaders(outTransport); - HTTPTransportUtils.setUTF8Encoding(outTransport); - HTTPTransportUtils.setContentType(outTransport, "text/html"); - - //evaluate template and write content to response - final Writer out = new OutputStreamWriter(outTransport.getOutgoingStream(), "UTF-8"); - velocityEngine.evaluate(context, out, "SAML2_POST_BINDING", new BufferedReader(new InputStreamReader(is))); - out.flush(); - - } catch (final Exception e) { - log.error("Error invoking Velocity template", e); - throw new MessageEncodingException("Error creating output document", e); - - } finally { - if (is != null) { - try { - is.close(); - - } catch (final IOException e) { - log.error("Can NOT close GUI-Template InputStream.", e); - } - } - - } - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java new file mode 100644 index 00000000..860eec64 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java @@ -0,0 +1,123 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration; +import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiFormBuilder; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.opensaml.common.binding.SAMLMessageContext; +import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; +import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.transport.http.HTTPOutTransport; +import org.opensaml.ws.transport.http.HTTPTransportUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * OpenSAML2 Post-Binding encoder that uses dynamic loaded templates. + * + * @author tlenz + * + */ +public class HttpPostEncoderWithOwnTemplate extends HTTPPostEncoder { + private static final Logger log = LoggerFactory.getLogger(HttpPostEncoderWithOwnTemplate.class); + + + private final VelocityEngine velocityEngine; + private final IVelocityGuiBuilderConfiguration guiConfig; + private final IVelocityGuiFormBuilder guiBuilder; + + /** + * Own Post-Binding encoder. + * + * @param guiConfig GUI configuration + * @param guiBuilder GUI builder implementation + * @param engine velocity engine + */ + public HttpPostEncoderWithOwnTemplate(final IVelocityGuiBuilderConfiguration guiConfig, + final IVelocityGuiFormBuilder guiBuilder, final VelocityEngine engine) { + super(engine, null); + this.velocityEngine = engine; + this.guiConfig = guiConfig; + this.guiBuilder = guiBuilder; + + } + + /** + * Base64 and POST encodes the outbound message and writes it to the outbound transport. + * + * @param messageContext current message context + * @param endpointUrl endpoint URL to which to encode message + * + * @throws MessageEncodingException thrown if there is a problem encoding the message + */ + @Override + protected void postEncode(final SAMLMessageContext messageContext, final String endpointUrl) + throws MessageEncodingException { + log.debug("Invoking Velocity template to create POST body"); + InputStream is = null; + try { + // build Velocity Context from GUI input paramters + final VelocityContext context = + guiBuilder.generateVelocityContextFromConfiguration(guiConfig); + + // load template + is = guiBuilder.getTemplateInputStream(guiConfig); + + // populate velocity context with SAML2 parameters + populateVelocityContext(context, messageContext, endpointUrl); + + // populate transport parameter + final HTTPOutTransport outTransport = + (HTTPOutTransport) messageContext.getOutboundMessageTransport(); + HTTPTransportUtils.addNoCacheHeaders(outTransport); + HTTPTransportUtils.setUTF8Encoding(outTransport); + HTTPTransportUtils.setContentType(outTransport, "text/html"); + + // evaluate template and write content to response + final Writer out = new OutputStreamWriter(outTransport.getOutgoingStream(), "UTF-8"); + velocityEngine.evaluate(context, out, "SAML2_POST_BINDING", + new BufferedReader(new InputStreamReader(is))); + out.flush(); + + } catch (final Exception e) { + log.error("Error invoking Velocity template", e); + throw new MessageEncodingException("Error creating output document", e); + + } finally { + if (is != null) { + try { + is.close(); + + } catch (final IOException e) { + log.error("Can NOT close GUI-Template InputStream.", e); + } + } + + } + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/KeyStoreX509CredentialAdapter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/KeyStoreX509CredentialAdapter.java index 2f3912ca..d84b407f 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/KeyStoreX509CredentialAdapter.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/KeyStoreX509CredentialAdapter.java @@ -1,56 +1,53 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml; import java.security.KeyStore; - import org.opensaml.xml.security.x509.X509Credential; /** + * OpenSAML2 KeyStore adapter. + * * @author tlenz * */ -public class KeyStoreX509CredentialAdapter extends - org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter { - - /** - * @param store - * @param alias - * @param password - */ - public KeyStoreX509CredentialAdapter(KeyStore store, String alias, - char[] password) { - super(store, alias, password); - } - - public Class<? extends X509Credential> getCredentialType() { - return X509Credential.class; - } - +public class KeyStoreX509CredentialAdapter + extends org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter { + + /** + * Get an OpenSAML2 keystore. + * + * @param store Java KeyStore + * @param alias Key alias + * @param password key Password + */ + public KeyStoreX509CredentialAdapter(final KeyStore store, final String alias, + final char[] password) { + super(store, alias, password); + } + + @Override + public Class<? extends X509Credential> getCredentialType() { + return X509Credential.class; + } + } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java index 544dc9f5..2def1446 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java @@ -1,31 +1,25 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafDefaultSaml2Bootstrap; import org.opensaml.common.binding.SAMLMessageContext; import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder; import org.opensaml.ws.message.MessageContext; @@ -33,49 +27,49 @@ import org.opensaml.ws.message.encoder.MessageEncodingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EAAFDefaultSAML2Bootstrap; - /** + * Create deflate encoded SAML2 redirect-binding informations. + * * @author tlenz * */ public class StringRedirectDeflateEncoder extends HTTPRedirectDeflateEncoder { - private static final Logger log = LoggerFactory.getLogger(StringRedirectDeflateEncoder.class); - - private String redirectURL = null; - - public void encode(MessageContext messageContext) - throws MessageEncodingException { - if (!(messageContext instanceof SAMLMessageContext)) { - log.error("Invalid message context type, this encoder only support SAMLMessageContext"); - throw new MessageEncodingException( - "Invalid message context type, this encoder only support SAMLMessageContext"); - } + private static final Logger log = LoggerFactory.getLogger(StringRedirectDeflateEncoder.class); + + private String redirectUrl = null; + + @Override + public void encode(final MessageContext messageContext) throws MessageEncodingException { + if (!(messageContext instanceof SAMLMessageContext)) { + log.error("Invalid message context type, this encoder only support SAMLMessageContext"); + throw new MessageEncodingException( + "Invalid message context type, this encoder only support SAMLMessageContext"); + } + + // load default PVP security configurations + EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration(); + + final SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext; + + final String endpointUrl = getEndpointURL(samlMsgCtx).buildURL(); - //load default PVP security configurations - EAAFDefaultSAML2Bootstrap.initializeDefaultPVPConfiguration(); - - SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext; + setResponseDestination(samlMsgCtx.getOutboundSAMLMessage(), endpointUrl); - String endpointURL = getEndpointURL(samlMsgCtx).buildURL(); + removeSignature(samlMsgCtx); - setResponseDestination(samlMsgCtx.getOutboundSAMLMessage(), endpointURL); + final String encodedMessage = deflateAndBase64Encode(samlMsgCtx.getOutboundSAMLMessage()); - removeSignature(samlMsgCtx); + redirectUrl = buildRedirectURL(samlMsgCtx, endpointUrl, encodedMessage); + } - String encodedMessage = deflateAndBase64Encode(samlMsgCtx - .getOutboundSAMLMessage()); + /** + * Get generated redirect URL. + * + * @return the redirectURL + */ + public String getRedirectUrl() { + return redirectUrl; + } - redirectURL = buildRedirectURL(samlMsgCtx, endpointURL, - encodedMessage); - } - /** - * @return the redirectURL - */ - public String getRedirectURL() { - return redirectURL; - } - - } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EAAFDefaultSAML2Bootstrap.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EAAFDefaultSAML2Bootstrap.java deleted file mode 100644 index 266b6e5f..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EAAFDefaultSAML2Bootstrap.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize; - -import org.opensaml.Configuration; -import org.opensaml.DefaultBootstrap; -import org.opensaml.xml.ConfigurationException; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttributes; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestedAttributeBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestedAttributeMarshaller; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestedAttributeUnmarshaller; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestedAttributesBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestedAttributesMarshaller; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestedAttributesUnmarshaller; - -/** - * @author tlenz - * - */ -public class EAAFDefaultSAML2Bootstrap extends DefaultBootstrap { - - public static synchronized void bootstrap() throws ConfigurationException { - - initializeXMLSecurity(); - - initializeXMLTooling(); - - initializeArtifactBuilderFactories(); - - initializeGlobalSecurityConfiguration(); - - initializeParserPool(); - - initializeESAPI(); - - initializeExtenstions(); - - } - - private static void initializeExtenstions() { - Configuration.registerObjectProvider( - EAAFRequestedAttribute.DEFAULT_ELEMENT_NAME, - new EAAFRequestedAttributeBuilder(), - new EAAFRequestedAttributeMarshaller(), - new EAAFRequestedAttributeUnmarshaller() - ); - - Configuration.registerObjectProvider( - EAAFRequestedAttributes.DEFAULT_ELEMENT_NAME, - new EAAFRequestedAttributesBuilder(), - new EAAFRequestedAttributesMarshaller(), - new EAAFRequestedAttributesUnmarshaller() - ); - - } - - public static void initializeDefaultPVPConfiguration() { - initializeGlobalSecurityConfiguration(); - - } - - /** - * Initializes the default global security configuration. - */ - protected static void initializeGlobalSecurityConfiguration() { - Configuration.setGlobalSecurityConfiguration(EAAFDefaultSecurityConfigurationBootstrap.buildDefaultConfig()); - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EAAFDefaultSecurityConfigurationBootstrap.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EAAFDefaultSecurityConfigurationBootstrap.java deleted file mode 100644 index ddd5b13e..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EAAFDefaultSecurityConfigurationBootstrap.java +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize; - -import org.opensaml.xml.encryption.EncryptionConstants; -import org.opensaml.xml.security.BasicSecurityConfiguration; -import org.opensaml.xml.security.DefaultSecurityConfigurationBootstrap; -import org.opensaml.xml.security.credential.BasicKeyInfoGeneratorFactory; -import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorManager; -import org.opensaml.xml.security.keyinfo.NamedKeyInfoGeneratorManager; -import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; -import org.opensaml.xml.signature.SignatureConstants; - -/** - * @author tlenz - * - */ -public class EAAFDefaultSecurityConfigurationBootstrap extends - DefaultSecurityConfigurationBootstrap { - - public static BasicSecurityConfiguration buildDefaultConfig() { - BasicSecurityConfiguration config = new BasicSecurityConfiguration(); - - populateSignatureParams(config); - populateEncryptionParams(config); - populateKeyInfoCredentialResolverParams(config); - populateKeyInfoGeneratorManager(config); - populateKeyParams(config); - - return config; - } - - protected static void populateKeyInfoGeneratorManager( - BasicSecurityConfiguration config) { - NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager(); - config.setKeyInfoGeneratorManager(namedManager); - - namedManager.setUseDefaultManager(true); - KeyInfoGeneratorManager defaultManager = namedManager - .getDefaultManager(); - - BasicKeyInfoGeneratorFactory basicFactory = new BasicKeyInfoGeneratorFactory(); - basicFactory.setEmitPublicKeyValue(true); - - X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory(); - x509Factory.setEmitEntityCertificate(true); - - defaultManager.registerFactory(basicFactory); - defaultManager.registerFactory(x509Factory); - } - - protected static void populateSignatureParams( - BasicSecurityConfiguration config) { - - //use SHA256 instead of SHA1 - config.registerSignatureAlgorithmURI("RSA", - SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - - config.registerSignatureAlgorithmURI("DSA", - "http://www.w3.org/2000/09/xmldsig#dsa-sha1"); - - //use SHA256 instead of SHA1 - config.registerSignatureAlgorithmURI("EC", - SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256); - - //use SHA256 instead of SHA1 - config.registerSignatureAlgorithmURI("AES", - SignatureConstants.ALGO_ID_MAC_HMAC_SHA256); - - - config.registerSignatureAlgorithmURI("DESede", - SignatureConstants.ALGO_ID_MAC_HMAC_SHA256); - - config.setSignatureCanonicalizationAlgorithm("http://www.w3.org/2001/10/xml-exc-c14n#"); - config.setSignatureHMACOutputLength(null); - - //use SHA256 instead of SHA1 - config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256); - } - - protected static void populateEncryptionParams( - BasicSecurityConfiguration config) { - config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(128), - "http://www.w3.org/2001/04/xmlenc#aes128-cbc"); - config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(192), - "http://www.w3.org/2001/04/xmlenc#aes192-cbc"); - config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(256), - "http://www.w3.org/2001/04/xmlenc#aes256-cbc"); - - //support GCM mode - config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(128), - EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM); - - config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(192), - EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM); - - config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(256), - EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM); - - - config.registerDataEncryptionAlgorithmURI("DESede", - Integer.valueOf(168), - "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"); - config.registerDataEncryptionAlgorithmURI("DESede", - Integer.valueOf(192), - "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"); - - config.registerKeyTransportEncryptionAlgorithmURI("RSA", null, "AES", - "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"); - - config.registerKeyTransportEncryptionAlgorithmURI("RSA", null, - "DESede", "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"); - - config.registerKeyTransportEncryptionAlgorithmURI("AES", - Integer.valueOf(128), null, - "http://www.w3.org/2001/04/xmlenc#kw-aes128"); - config.registerKeyTransportEncryptionAlgorithmURI("AES", - Integer.valueOf(192), null, - "http://www.w3.org/2001/04/xmlenc#kw-aes192"); - config.registerKeyTransportEncryptionAlgorithmURI("AES", - Integer.valueOf(256), null, - "http://www.w3.org/2001/04/xmlenc#kw-aes256"); - config.registerKeyTransportEncryptionAlgorithmURI("DESede", - Integer.valueOf(168), null, - "http://www.w3.org/2001/04/xmlenc#kw-tripledes"); - config.registerKeyTransportEncryptionAlgorithmURI("DESede", - Integer.valueOf(192), null, - "http://www.w3.org/2001/04/xmlenc#kw-tripledes"); - - config.setAutoGeneratedDataEncryptionKeyAlgorithmURI("http://www.w3.org/2001/04/xmlenc#aes128-cbc"); - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java new file mode 100644 index 00000000..9db8e5e7 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize; + +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeMarshaller; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeUnmarshaller; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesMarshaller; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesUnmarshaller; +import org.opensaml.DefaultBootstrap; +import org.opensaml.xml.ConfigurationException; + +/** + * EAAF specific OpenSAML Initializer. + * + * @author tlenz + * + */ +public class EaafDefaultSaml2Bootstrap extends DefaultBootstrap { + + /** + * OpenSAML2 bootstrap. + * + * @throws ConfigurationException In case of an error + */ + public static synchronized void bootstrap() throws ConfigurationException { + + initializeXMLSecurity(); + + initializeXMLTooling(); + + initializeArtifactBuilderFactories(); + + initializeGlobalSecurityConfiguration(); + + initializeParserPool(); + + initializeESAPI(); + + initializeExtenstions(); + + } + + private static void initializeExtenstions() { + org.opensaml.xml.Configuration.registerObjectProvider( + EaafRequestedAttribute.DEFAULT_ELEMENT_NAME, new EaafRequestedAttributeBuilder(), + new EaafRequestedAttributeMarshaller(), new EaafRequestedAttributeUnmarshaller()); + + org.opensaml.xml.Configuration.registerObjectProvider( + EaafRequestedAttributes.DEFAULT_ELEMENT_NAME, new EaafRequestedAttributesBuilder(), + new EaafRequestedAttributesMarshaller(), new EaafRequestedAttributesUnmarshaller()); + + } + + public static void initializeDefaultPvpConfiguration() { + initializeGlobalSecurityConfiguration(); + + } + + /** + * Initializes the default global security configuration. + */ + protected static void initializeGlobalSecurityConfiguration() { + org.opensaml.xml.Configuration.setGlobalSecurityConfiguration( + EaafDefaultSecurityConfigurationBootstrap.buildDefaultConfig()); + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java new file mode 100644 index 00000000..a1a7e9d2 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java @@ -0,0 +1,141 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize; + +import org.opensaml.xml.encryption.EncryptionConstants; +import org.opensaml.xml.security.BasicSecurityConfiguration; +import org.opensaml.xml.security.DefaultSecurityConfigurationBootstrap; +import org.opensaml.xml.security.credential.BasicKeyInfoGeneratorFactory; +import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorManager; +import org.opensaml.xml.security.keyinfo.NamedKeyInfoGeneratorManager; +import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; +import org.opensaml.xml.signature.SignatureConstants; + +/** + * EAAF specific OpenSAML2 security configuration. + * + * @author tlenz + * + */ +public class EaafDefaultSecurityConfigurationBootstrap + extends DefaultSecurityConfigurationBootstrap { + + /** + * Build EAAF security configuration for OpenSAML2. + * + * @return + */ + public static BasicSecurityConfiguration buildDefaultConfig() { + final BasicSecurityConfiguration config = new BasicSecurityConfiguration(); + + populateSignatureParams(config); + populateEncryptionParams(config); + populateKeyInfoCredentialResolverParams(config); + populateKeyInfoGeneratorManager(config); + populateKeyParams(config); + + return config; + } + + protected static void populateKeyInfoGeneratorManager(final BasicSecurityConfiguration config) { + final NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager(); + config.setKeyInfoGeneratorManager(namedManager); + + namedManager.setUseDefaultManager(true); + final KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager(); + + final BasicKeyInfoGeneratorFactory basicFactory = new BasicKeyInfoGeneratorFactory(); + basicFactory.setEmitPublicKeyValue(true); + + final X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory(); + x509Factory.setEmitEntityCertificate(true); + + defaultManager.registerFactory(basicFactory); + defaultManager.registerFactory(x509Factory); + } + + protected static void populateSignatureParams(final BasicSecurityConfiguration config) { + + // use SHA256 instead of SHA1 + config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + + config.registerSignatureAlgorithmURI("DSA", "http://www.w3.org/2000/09/xmldsig#dsa-sha1"); + + // use SHA256 instead of SHA1 + config.registerSignatureAlgorithmURI("EC", SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256); + + // use SHA256 instead of SHA1 + config.registerSignatureAlgorithmURI("AES", SignatureConstants.ALGO_ID_MAC_HMAC_SHA256); + + + config.registerSignatureAlgorithmURI("DESede", SignatureConstants.ALGO_ID_MAC_HMAC_SHA256); + + config.setSignatureCanonicalizationAlgorithm("http://www.w3.org/2001/10/xml-exc-c14n#"); + config.setSignatureHMACOutputLength(null); + + // use SHA256 instead of SHA1 + config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256); + } + + protected static void populateEncryptionParams(final BasicSecurityConfiguration config) { + config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(128), + "http://www.w3.org/2001/04/xmlenc#aes128-cbc"); + config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(192), + "http://www.w3.org/2001/04/xmlenc#aes192-cbc"); + config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(256), + "http://www.w3.org/2001/04/xmlenc#aes256-cbc"); + + // support GCM mode + config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(128), + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM); + + config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(192), + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM); + + config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(256), + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM); + + + config.registerDataEncryptionAlgorithmURI("DESede", Integer.valueOf(168), + "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"); + config.registerDataEncryptionAlgorithmURI("DESede", Integer.valueOf(192), + "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"); + + config.registerKeyTransportEncryptionAlgorithmURI("RSA", null, "AES", + "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"); + + config.registerKeyTransportEncryptionAlgorithmURI("RSA", null, "DESede", + "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"); + + config.registerKeyTransportEncryptionAlgorithmURI("AES", Integer.valueOf(128), null, + "http://www.w3.org/2001/04/xmlenc#kw-aes128"); + config.registerKeyTransportEncryptionAlgorithmURI("AES", Integer.valueOf(192), null, + "http://www.w3.org/2001/04/xmlenc#kw-aes192"); + config.registerKeyTransportEncryptionAlgorithmURI("AES", Integer.valueOf(256), null, + "http://www.w3.org/2001/04/xmlenc#kw-aes256"); + config.registerKeyTransportEncryptionAlgorithmURI("DESede", Integer.valueOf(168), null, + "http://www.w3.org/2001/04/xmlenc#kw-tripledes"); + config.registerKeyTransportEncryptionAlgorithmURI("DESede", Integer.valueOf(192), null, + "http://www.w3.org/2001/04/xmlenc#kw-tripledes"); + + config.setAutoGeneratedDataEncryptionKeyAlgorithmURI( + "http://www.w3.org/2001/04/xmlenc#aes128-cbc"); + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EAAFRequestedAttributeImpl.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EAAFRequestedAttributeImpl.java deleted file mode 100644 index ed169d8c..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EAAFRequestedAttributeImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.reqattr; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.opensaml.common.impl.AbstractSAMLObject; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.schema.XSBooleanValue; -import org.opensaml.xml.util.AttributeMap; -import org.opensaml.xml.util.XMLObjectChildrenList; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; - -public class EAAFRequestedAttributeImpl extends AbstractSAMLObject implements EAAFRequestedAttribute { - - private final XMLObjectChildrenList<XMLObject> attributeValues; - private String friendlyName; - private String isRequired; - private String name; - private String nameFormat; - private AttributeMap unknownAttributes; - - public EAAFRequestedAttributeImpl(String namespaceURI, String elementLocalName, String namespacePrefix) { - super(namespaceURI, elementLocalName, namespacePrefix); - unknownAttributes = new AttributeMap(this); - attributeValues = new XMLObjectChildrenList<XMLObject>(this); - - } - - public final List<XMLObject> getAttributeValues() { - return attributeValues; - } - - public final String getFriendlyName() { - return friendlyName; - } - - public final String getIsRequiredXSBoolean() { - return isRequired; - } - - public final String getName() { - return name; - } - - public final String getNameFormat() { - return nameFormat; - } - - public final List<XMLObject> getOrderedChildren() { - final List<XMLObject> children = new ArrayList<XMLObject>(); - children.addAll(attributeValues); - return Collections.unmodifiableList(children); - } - - - public final AttributeMap getUnknownAttributes() { - return unknownAttributes; - } - - - public final void setFriendlyName(final String newFriendlyName) { - this.friendlyName = prepareForAssignment(this.friendlyName, - newFriendlyName); - } - - - public final void setIsRequired(final String newIsRequired) { - isRequired = prepareForAssignment(this.isRequired, newIsRequired); - - } - - - public final void setName(final String newName) { - this.name = prepareForAssignment(this.name, newName); - } - - - public final void setNameFormat(final String newNameFormat) { - this.nameFormat = prepareForAssignment(this.nameFormat, newNameFormat); - } - - - public final void setUnknownAttributes(final AttributeMap newUnknownAttr) { - this.unknownAttributes = newUnknownAttr; - } - - @Override - public XSBooleanValue isRequiredXSBoolean() { - return XSBooleanValue.valueOf(isRequired); - } - - @Override - public void setIsRequired(Boolean aBoolean) { - this.isRequired = String.valueOf(aBoolean); - } - - @Override - public void setIsRequired(XSBooleanValue xsBooleanValue) { - this.isRequired = String.valueOf(xsBooleanValue); - } - - @Override - public Boolean isRequired() { - return Boolean.parseBoolean(isRequired); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EAAFRequestedAttributesImpl.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EAAFRequestedAttributesImpl.java deleted file mode 100644 index b85d4791..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EAAFRequestedAttributesImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.reqattr; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.opensaml.common.impl.AbstractSAMLObject; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.util.IndexedXMLObjectChildrenList; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttributes; - -public class EAAFRequestedAttributesImpl extends AbstractSAMLObject implements EAAFRequestedAttributes { - - private final IndexedXMLObjectChildrenList<XMLObject> indexedChildren; - - public EAAFRequestedAttributesImpl(String namespaceURI, String elementLocalName, String namespacePrefix) { - super(namespaceURI, elementLocalName, namespacePrefix); - indexedChildren = new IndexedXMLObjectChildrenList<XMLObject>(this); - } - - @Override - public List<XMLObject> getOrderedChildren() { - final List<XMLObject> children = new ArrayList<XMLObject>(); - children.addAll(indexedChildren); - return Collections.unmodifiableList(children); - - } - - @Override - public List<EAAFRequestedAttribute> getAttributes() { - return (List<EAAFRequestedAttribute>) indexedChildren - .subList(EAAFRequestedAttribute.DEFAULT_ELEMENT_NAME); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EaafRequestedAttributeImpl.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EaafRequestedAttributeImpl.java new file mode 100644 index 00000000..1ceb5adc --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EaafRequestedAttributeImpl.java @@ -0,0 +1,149 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.reqattr; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import org.opensaml.common.impl.AbstractSAMLObject; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.schema.XSBooleanValue; +import org.opensaml.xml.util.AttributeMap; +import org.opensaml.xml.util.XMLObjectChildrenList; + +public class EaafRequestedAttributeImpl extends AbstractSAMLObject + implements EaafRequestedAttribute { + + private final XMLObjectChildrenList<XMLObject> attributeValues; + private String friendlyName; + private String isRequired; + private String name; + private String nameFormat; + private AttributeMap unknownAttributes; + + /** + * Build an EAAF specific requested attribute. + * + * @param namespaceUri Attribute namespace + * @param elementLocalName Attribute name + * @param namespacePrefix Attribute namespace prefix + */ + public EaafRequestedAttributeImpl(final String namespaceUri, final String elementLocalName, + final String namespacePrefix) { + super(namespaceUri, elementLocalName, namespacePrefix); + unknownAttributes = new AttributeMap(this); + attributeValues = new XMLObjectChildrenList<>(this); + + } + + @Override + public final List<XMLObject> getAttributeValues() { + return attributeValues; + } + + @Override + public final String getFriendlyName() { + return friendlyName; + } + + @Override + public final String getIsRequiredXsBoolean() { + return isRequired; + } + + @Override + public final String getName() { + return name; + } + + @Override + public final String getNameFormat() { + return nameFormat; + } + + @Override + public final List<XMLObject> getOrderedChildren() { + final List<XMLObject> children = new ArrayList<>(); + children.addAll(attributeValues); + return Collections.unmodifiableList(children); + } + + + @Override + public final AttributeMap getUnknownAttributes() { + return unknownAttributes; + } + + + @Override + public final void setFriendlyName(final String newFriendlyName) { + this.friendlyName = prepareForAssignment(this.friendlyName, newFriendlyName); + } + + + @Override + public void setIsRequired(final Boolean aboolean) { + this.isRequired = String.valueOf(aboolean); + } + + @Override + public void setIsRequired(final XSBooleanValue xsBooleanValue) { + this.isRequired = String.valueOf(xsBooleanValue); + } + + @Override + public final void setIsRequired(final String newIsRequired) { + isRequired = prepareForAssignment(this.isRequired, newIsRequired); + + } + + + @Override + public final void setName(final String newName) { + this.name = prepareForAssignment(this.name, newName); + } + + + @Override + public final void setNameFormat(final String newNameFormat) { + this.nameFormat = prepareForAssignment(this.nameFormat, newNameFormat); + } + + + public final void setUnknownAttributes(final AttributeMap newUnknownAttr) { + this.unknownAttributes = newUnknownAttr; + } + + @Override + public XSBooleanValue isRequiredXSBoolean() { + return XSBooleanValue.valueOf(isRequired); + } + + + + + + @Override + public Boolean isRequired() { + return Boolean.parseBoolean(isRequired); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EaafRequestedAttributesImpl.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EaafRequestedAttributesImpl.java new file mode 100644 index 00000000..3b447538 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/reqattr/EaafRequestedAttributesImpl.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.reqattr; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; +import org.opensaml.common.impl.AbstractSAMLObject; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.util.IndexedXMLObjectChildrenList; + +public class EaafRequestedAttributesImpl extends AbstractSAMLObject + implements EaafRequestedAttributes { + + private final IndexedXMLObjectChildrenList<XMLObject> indexedChildren; + + public EaafRequestedAttributesImpl(final String namespaceUri, final String elementLocalName, + final String namespacePrefix) { + super(namespaceUri, elementLocalName, namespacePrefix); + indexedChildren = new IndexedXMLObjectChildrenList<>(this); + } + + @Override + public List<XMLObject> getOrderedChildren() { + final List<XMLObject> children = new ArrayList<>(); + children.addAll(indexedChildren); + return Collections.unmodifiableList(children); + + } + + @Override + public List<EaafRequestedAttribute> getAttributes() { + return (List<EaafRequestedAttribute>) indexedChildren + .subList(EaafRequestedAttribute.DEFAULT_ELEMENT_NAME); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java index acc5357e..ea361f11 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java @@ -1,36 +1,32 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.utils; import java.security.KeyStore; import java.security.PrivateKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.RSAPrivateKey; - +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.KeyStoreX509CredentialAdapter; import org.apache.commons.lang3.StringUtils; import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.security.credential.UsageType; @@ -40,186 +36,210 @@ import org.opensaml.xml.signature.SignatureConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; -import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.KeyStoreX509CredentialAdapter; - public abstract class AbstractCredentialProvider { - - private static final Logger log = LoggerFactory.getLogger(AbstractCredentialProvider.class); - - private KeyStore keyStore = null; - - /** - * Get a friendlyName for this keyStore implementation - * This friendlyName is used for logging - * - * @return keyStore friendlyName - */ - public abstract String getFriendlyName(); - - /** - * Get KeyStore - * - * @return URL to the keyStore - * @throws EAAFException - */ - public abstract String getKeyStoreFilePath() throws EAAFException; - - /** - * Get keyStore password - * - * @return Password of the keyStore - */ - public abstract String getKeyStorePassword(); - - /** - * Get alias of key for metadata signing - * - * @return key alias - */ - public abstract String getMetadataKeyAlias(); - - /** - * Get password of key for metadata signing - * - * @return key password - */ - public abstract String getMetadataKeyPassword(); - - /** - * Get alias of key for request/response signing - * - * @return key alias - */ - public abstract String getSignatureKeyAlias(); - - /** - * Get password of key for request/response signing - * - * @return key password - */ - public abstract String getSignatureKeyPassword(); - - /** - * Get alias of key for IDP response encryption - * - * @return key alias - */ - public abstract String getEncryptionKeyAlias(); - - /** - * Get password of key for IDP response encryption - * - * @return key password - */ - public abstract String getEncryptionKeyPassword(); - - - public X509Credential getIDPMetaDataSigningCredential() - throws CredentialsNotAvailableException { - try { - - if (keyStore == null) - keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), - getKeyStorePassword()); - - KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter( - keyStore, getMetadataKeyAlias(), getMetadataKeyPassword().toCharArray()); - - credentials.setUsageType(UsageType.SIGNING); - if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) { - log.error(getFriendlyName() + " Metadata Signing credentials is not found or contains no PrivateKey."); - throw new CredentialsNotAvailableException("config.27", new Object[]{getFriendlyName() + " Assertion Signing credentials (Alias: " - + getMetadataKeyAlias() + ") is not found or contains no PrivateKey."}); - - } - return credentials; - } catch (Exception e) { - log.error("Failed to generate " + getFriendlyName() + " Metadata Signing credentials"); - e.printStackTrace(); - throw new CredentialsNotAvailableException("config.27", new Object[]{e.getMessage()}, e); - } - } - - public X509Credential getIDPAssertionSigningCredential() - throws CredentialsNotAvailableException { - try { - if (keyStore == null) - keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), - getKeyStorePassword()); - - KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter( - keyStore, getSignatureKeyAlias(), getSignatureKeyPassword().toCharArray()); - - credentials.setUsageType(UsageType.SIGNING); - if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) { - log.error(getFriendlyName() + " Assertion Signing credentials is not found or contains no PrivateKey."); - throw new CredentialsNotAvailableException("config.27", new Object[]{getFriendlyName() + " Assertion Signing credentials (Alias: " - + getSignatureKeyAlias() + ") is not found or contains no PrivateKey."}); - - } - - return (X509Credential) credentials; - } catch (Exception e) { - log.error("Failed to generate " + getFriendlyName() + " Assertion Signing credentials"); - e.printStackTrace(); - throw new CredentialsNotAvailableException("config.27", new Object[]{e.getMessage()}, e); - } - } - - public X509Credential getIDPAssertionEncryptionCredential() - throws CredentialsNotAvailableException { - try { - if (keyStore == null) - keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), - getKeyStorePassword()); - - //if no encryption key is configured return null - if (StringUtils.isEmpty(getEncryptionKeyAlias())) - return null; - - KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter( - keyStore, getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray()); - - credentials.setUsageType(UsageType.ENCRYPTION); - - if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) { - log.error(getFriendlyName() + " Assertion Encryption credentials is not found or contains no PrivateKey."); - throw new CredentialsNotAvailableException("config.27", new Object[]{getFriendlyName() + " Assertion Encryption credentials (Alias: " - + getEncryptionKeyAlias() + ") is not found or contains no PrivateKey."}); - - } - - return (X509Credential) credentials; - - } catch (Exception e) { - log.error("Failed to generate " + getFriendlyName() + " Assertion Encryption credentials"); - e.printStackTrace(); - throw new CredentialsNotAvailableException("config.27", new Object[]{e.getMessage()}, e); - } - } - - public static Signature getIDPSignature(Credential credentials) { - PrivateKey privatekey = credentials.getPrivateKey(); - Signature signer = SAML2Utils.createSAMLObject(Signature.class); - - if (privatekey instanceof RSAPrivateKey) { - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - - } else if (privatekey instanceof ECPrivateKey) { - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256); - - } else { - log.warn("Could NOT evaluate the Private-Key type from " + credentials.getEntityId() + " credential."); - - - } - - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(credentials); - return signer; - - } + + private static final Logger log = LoggerFactory.getLogger(AbstractCredentialProvider.class); + + private KeyStore keyStore = null; + + /** + * Get a friendlyName for this keyStore implementation This friendlyName is used for logging. + * + * @return keyStore friendlyName + */ + public abstract String getFriendlyName(); + + /** + * Get KeyStore. + * + * @return URL to the keyStore + * @throws EaafException In case of an invalid filepath + */ + public abstract String getKeyStoreFilePath() throws EaafException; + + /** + * Get keyStore password. + * + * @return Password of the keyStore + */ + public abstract String getKeyStorePassword(); + + /** + * Get alias of key for metadata signing. + * + * @return key alias + */ + public abstract String getMetadataKeyAlias(); + + /** + * Get password of key for metadata signing. + * + * @return key password + */ + public abstract String getMetadataKeyPassword(); + + /** + * Get alias of key for request/response signing. + * + * @return key alias + */ + public abstract String getSignatureKeyAlias(); + + /** + * Get password of key for request/response signing. + * + * @return key password + */ + public abstract String getSignatureKeyPassword(); + + /** + * Get alias of key for IDP response encryption. + * + * @return key alias + */ + public abstract String getEncryptionKeyAlias(); + + /** + * Get password of key for IDP response encryption. + * + * @return key password + */ + public abstract String getEncryptionKeyPassword(); + + + /** + * Get Credentials to sign metadata. + * + * @return Credentials + * @throws CredentialsNotAvailableException In case of a credential error + */ + public X509Credential getIdpMetaDataSigningCredential() throws CredentialsNotAvailableException { + try { + + if (keyStore == null) { + keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword()); + } + + final KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(keyStore, + getMetadataKeyAlias(), getMetadataKeyPassword().toCharArray()); + + credentials.setUsageType(UsageType.SIGNING); + if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) { + log.error(getFriendlyName() + + " Metadata Signing credentials is not found or contains no PrivateKey."); + throw new CredentialsNotAvailableException("config.27", + new Object[] {getFriendlyName() + " Assertion Signing credentials (Alias: " + + getMetadataKeyAlias() + ") is not found or contains no PrivateKey."}); + + } + return credentials; + } catch (final Exception e) { + log.error("Failed to generate " + getFriendlyName() + " Metadata Signing credentials"); + e.printStackTrace(); + throw new CredentialsNotAvailableException("config.27", new Object[] {e.getMessage()}, e); + } + } + + /** + * Get Credentials to sign Assertion. + * + * @return Credentials + * @throws CredentialsNotAvailableException In case of a credential error + */ + public X509Credential getIdpAssertionSigningCredential() throws CredentialsNotAvailableException { + try { + if (keyStore == null) { + keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword()); + } + + final KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(keyStore, + getSignatureKeyAlias(), getSignatureKeyPassword().toCharArray()); + + credentials.setUsageType(UsageType.SIGNING); + if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) { + log.error(getFriendlyName() + + " Assertion Signing credentials is not found or contains no PrivateKey."); + throw new CredentialsNotAvailableException("config.27", + new Object[] {getFriendlyName() + " Assertion Signing credentials (Alias: " + + getSignatureKeyAlias() + ") is not found or contains no PrivateKey."}); + + } + + return credentials; + } catch (final Exception e) { + log.error("Failed to generate " + getFriendlyName() + " Assertion Signing credentials"); + e.printStackTrace(); + throw new CredentialsNotAvailableException("config.27", new Object[] {e.getMessage()}, e); + } + } + + /** + * Get Credentials to encrypt assertion. + * + * @return Credentials + * @throws CredentialsNotAvailableException In case of a credential error + */ + public X509Credential getIdpAssertionEncryptionCredential() + throws CredentialsNotAvailableException { + try { + if (keyStore == null) { + keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword()); + } + + // if no encryption key is configured return null + if (StringUtils.isEmpty(getEncryptionKeyAlias())) { + return null; + } + + final KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(keyStore, + getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray()); + + credentials.setUsageType(UsageType.ENCRYPTION); + + if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) { + log.error(getFriendlyName() + + " Assertion Encryption credentials is not found or contains no PrivateKey."); + throw new CredentialsNotAvailableException("config.27", + new Object[] {getFriendlyName() + " Assertion Encryption credentials (Alias: " + + getEncryptionKeyAlias() + ") is not found or contains no PrivateKey."}); + + } + + return credentials; + + } catch (final Exception e) { + log.error("Failed to generate " + getFriendlyName() + " Assertion Encryption credentials"); + e.printStackTrace(); + throw new CredentialsNotAvailableException("config.27", new Object[] {e.getMessage()}, e); + } + } + + /** + * Get an XML signature object. + * + * @param credentials Credentials for signing + * @return OpenSAML Signature object + */ + public static Signature getIdpSignature(final Credential credentials) { + final PrivateKey privatekey = credentials.getPrivateKey(); + final Signature signer = Saml2Utils.createSamlObject(Signature.class); + + if (privatekey instanceof RSAPrivateKey) { + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + + } else if (privatekey instanceof ECPrivateKey) { + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256); + + } else { + log.warn("Could NOT evaluate the Private-Key type from " + credentials.getEntityId() + + " credential."); + + + } + + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(credentials); + return signer; + + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java deleted file mode 100644 index 8e7183d3..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.utils; - -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.modules.pvp2.exception.QAANotAllowedException; - -/** - * @author tlenz - * - */ -public class QAALevelVerifier { - - private static final Logger log = LoggerFactory.getLogger(QAALevelVerifier.class); - - private static boolean verifyQAALevel(String qaaAuth, String requiredLoA, String matchingMode) throws QAANotAllowedException { - //to MINIMUM machting - if (EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM.equals(matchingMode)) { - log.trace("Perfom LoA matching in 'MINIMUM' mode ... "); - if (EAAFConstants.EIDAS_LOA_LOW.equals(requiredLoA) && - (EAAFConstants.EIDAS_LOA_LOW.equals(qaaAuth) || - EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth) || - EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth)) - ) - return true; - - else if (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(requiredLoA) && - (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth) || - EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth)) - ) - return true; - - else if (EAAFConstants.EIDAS_LOA_HIGH.equals(requiredLoA) && EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth)) - return true; - - } else if (EAAFConstants.EIDAS_LOA_MATCHING_EXACT.equals(matchingMode)) { - //to EXACT matching - log.trace("Perfom LoA matching in 'EXACT' mode ... "); - if (qaaAuth.equals(requiredLoA)) { - log.debug("Required LoA fits LoA from authentication. Continue auth process ... "); - return true; - - } - - } else { - log.warn("LoA matching-mode:" + matchingMode + " is NOT supported by this implementation"); - throw new QAANotAllowedException(qaaAuth, requiredLoA, matchingMode); - - } - - return false; - - } - - public static void verifyQAALevel(String qaaAuth, List<String> requiredLoAs, String matchingMode) throws QAANotAllowedException { - log.trace("Starting LoA verification: authLoA: " + qaaAuth - + " requiredLoA: " + StringUtils.join(requiredLoAs, "|") - + " matchingMode: " + matchingMode); - - boolean hasMatch = false; - for (String loa : requiredLoAs) { - if (verifyQAALevel(qaaAuth, loa, matchingMode)) - hasMatch = true; - - } - - if (!hasMatch) - throw new QAANotAllowedException(qaaAuth, StringUtils.join(requiredLoAs, "|"), matchingMode); - - else - log.debug("Requesed LoA fits LoA from authentication. Continue auth process ... "); - - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java new file mode 100644 index 00000000..876fa744 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java @@ -0,0 +1,106 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.utils; + +import java.util.List; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.modules.pvp2.exception.QaaNotAllowedException; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * EAAF LoA Level verifier checks if requested LoA matchs to LoA of authentication. + * + * + * @author tlenz + * + */ +public class QaaLevelVerifier { + + private static final Logger log = LoggerFactory.getLogger(QaaLevelVerifier.class); + + private static boolean verifyQaaLevel(final String qaaAuth, final String requiredLoA, + final String matchingMode) throws QaaNotAllowedException { + // to MINIMUM machting + if (EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM.equals(matchingMode)) { + log.trace("Perfom LoA matching in 'MINIMUM' mode ... "); + if (EAAFConstants.EIDAS_LOA_LOW.equals(requiredLoA) + && (EAAFConstants.EIDAS_LOA_LOW.equals(qaaAuth) + || EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth) + || EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))) { + return true; + } else if (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(requiredLoA) + && (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth) + || EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))) { + return true; + } else if (EAAFConstants.EIDAS_LOA_HIGH.equals(requiredLoA) + && EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth)) { + return true; + } + + } else if (EAAFConstants.EIDAS_LOA_MATCHING_EXACT.equals(matchingMode)) { + // to EXACT matching + log.trace("Perfom LoA matching in 'EXACT' mode ... "); + if (qaaAuth.equals(requiredLoA)) { + log.debug("Required LoA fits LoA from authentication. Continue auth process ... "); + return true; + + } + + } else { + log.warn("LoA matching-mode:" + matchingMode + " is NOT supported by this implementation"); + throw new QaaNotAllowedException(qaaAuth, requiredLoA, matchingMode); + + } + + return false; + + } + + /** + * Check LoA level. + * + * @param qaaAuth LoA of authentication + * @param requiredLoAs List of allowed LoA levels + * @param matchingMode LoA matching mode + * @throws QaaNotAllowedException If LoA does not match + */ + public static void verifyQaaLevel(final String qaaAuth, final List<String> requiredLoAs, + final String matchingMode) throws QaaNotAllowedException { + log.trace("Starting LoA verification: authLoA: " + qaaAuth + " requiredLoA: " + + StringUtils.join(requiredLoAs, "|") + " matchingMode: " + matchingMode); + + boolean hasMatch = false; + for (final String loa : requiredLoAs) { + if (verifyQaaLevel(qaaAuth, loa, matchingMode)) { + hasMatch = true; + } + + } + + if (!hasMatch) { + throw new QaaNotAllowedException(qaaAuth, StringUtils.join(requiredLoAs, "|"), matchingMode); + } else { + log.debug("Requesed LoA fits LoA from authentication. Continue auth process ... "); + } + + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java deleted file mode 100644 index d33ee6c6..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.utils; - -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.util.List; - -import javax.xml.namespace.QName; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.dom.DOMSource; -import javax.xml.validation.Schema; -import javax.xml.validation.Validator; - -import org.apache.commons.lang3.StringUtils; -import org.opensaml.Configuration; -import org.opensaml.common.impl.SecureRandomIdentifierGenerator; -import org.opensaml.common.xml.SAMLSchemaBuilder; -import org.opensaml.saml2.core.Attribute; -import org.opensaml.saml2.core.Status; -import org.opensaml.saml2.core.StatusCode; -import org.opensaml.saml2.metadata.AssertionConsumerService; -import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.opensaml.ws.soap.soap11.Body; -import org.opensaml.ws.soap.soap11.Envelope; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.XMLObjectBuilderFactory; -import org.opensaml.xml.io.Marshaller; -import org.opensaml.xml.io.MarshallingException; -import org.opensaml.xml.schema.XSString; -import org.opensaml.xml.schema.impl.XSStringBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; - -import at.gv.egiz.eaaf.core.impl.utils.Random; -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; - -public class SAML2Utils { - private static final Logger log = LoggerFactory.getLogger(SAML2Utils.class); - - public static <T> T createSAMLObject(final Class<T> clazz) { - try { - XMLObjectBuilderFactory builderFactory = Configuration - .getBuilderFactory(); - - QName defaultElementName = (QName) clazz.getDeclaredField( - "DEFAULT_ELEMENT_NAME").get(null); - @SuppressWarnings("unchecked") - T object = (T) builderFactory.getBuilder(defaultElementName) - .buildObject(defaultElementName); - return object; - } catch (Throwable e) { - e.printStackTrace(); - return null; - } - } - - public static String getSecureIdentifier() { - return "_".concat(Random.nextHexRandom16()); - - /*Bug-Fix: There are open problems with RandomNumberGenerator via Java SPI and Java JDK 8.121 - * Generation of a 16bit Random identifier FAILES with an Caused by: java.lang.ArrayIndexOutOfBoundsException - * Caused by: java.lang.ArrayIndexOutOfBoundsException - at iaik.security.random.o.engineNextBytes(Unknown Source) - at iaik.security.random.SecRandomSpi.engineNextBytes(Unknown Source) - at java.security.SecureRandom.nextBytes(SecureRandom.java:468) - at org.opensaml.common.impl.SecureRandomIdentifierGenerator.generateIdentifier(SecureRandomIdentifierGenerator.java:62) - at org.opensaml.common.impl.SecureRandomIdentifierGenerator.generateIdentifier(SecureRandomIdentifierGenerator.java:56) - at at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils.getSecureIdentifier(SAML2Utils.java:69) - */ - //return idGenerator.generateIdentifier(); - } - - private static SecureRandomIdentifierGenerator idGenerator; - - private static DocumentBuilder builder; - static { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - try { - builder = factory.newDocumentBuilder(); - } catch (ParserConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - try { - idGenerator = new SecureRandomIdentifierGenerator(); - } catch(NoSuchAlgorithmException e) { - e.printStackTrace(); - } - } - - public static Document asDOMDocument(XMLObject object) throws IOException, - MarshallingException, TransformerException { - Document document = builder.newDocument(); - Marshaller out = Configuration.getMarshallerFactory().getMarshaller( - object); - out.marshall(object, document); - return document; - } - - public static Status getSuccessStatus() { - Status status = SAML2Utils.createSAMLObject(Status.class); - StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class); - statusCode.setValue(StatusCode.SUCCESS_URI); - status.setStatusCode(statusCode); - return status; - } - - public static int getDefaultAssertionConsumerServiceIndex(SPSSODescriptor spSSODescriptor) { - - List<AssertionConsumerService> assertionConsumerList = spSSODescriptor.getAssertionConsumerServices(); - - for (AssertionConsumerService el : assertionConsumerList) { - if (el.isDefault()) - return el.getIndex(); - - } - - return 0; - } - - public static Envelope buildSOAP11Envelope(XMLObject payload) { - XMLObjectBuilderFactory bf = Configuration.getBuilderFactory(); - Envelope envelope = (Envelope) bf.getBuilder(Envelope.DEFAULT_ELEMENT_NAME).buildObject(Envelope.DEFAULT_ELEMENT_NAME); - Body body = (Body) bf.getBuilder(Body.DEFAULT_ELEMENT_NAME).buildObject(Body.DEFAULT_ELEMENT_NAME); - - body.getUnknownXMLObjects().add(payload); - envelope.setBody(body); - - return envelope; - } - - public static EAAFRequestedAttribute generateReqAuthnAttributeSimple(Attribute attr, boolean isRequired, String value) { - EAAFRequestedAttribute requested = SAML2Utils.createSAMLObject(EAAFRequestedAttribute.class); - requested.setName(attr.getName()); - requested.setNameFormat(attr.getNameFormat()); - requested.setFriendlyName(attr.getFriendlyName()); - requested.setIsRequired(String.valueOf(isRequired)); - List<XMLObject> attributeValues = requested.getAttributeValues(); - if (StringUtils.isNotEmpty(value)) { - XMLObject attributeValueForRequest = createAttributeValue(PVPConstants.EIDAS_REQUESTED_ATTRIBUTE_VALUE_TYPE, value); - attributeValues.add(attributeValueForRequest); - } - return requested; - - } - - public static void schemeValidation(XMLObject xmlObject) throws Exception { - try { - Schema test = SAMLSchemaBuilder.getSAML11Schema(); - Validator val = test.newValidator(); - DOMSource source = new DOMSource(xmlObject.getDOM()); - val.validate(source); - log.debug("SAML2 Scheme validation successful"); - return; - - } catch (Exception e) { - log.warn("SAML2 scheme validation FAILED.", e); - throw e; - - } - } - - private static XMLObject createAttributeValue(QName attributeValueType, String value) { - XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); - XSString stringValue = stringBuilder.buildObject(attributeValueType, XSString.TYPE_NAME); - stringValue.setValue(value); - return stringValue; - - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java new file mode 100644 index 00000000..1c7a9652 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java @@ -0,0 +1,247 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.utils; + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.Validator; +import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import org.apache.commons.lang3.StringUtils; +import org.opensaml.common.impl.SecureRandomIdentifierGenerator; +import org.opensaml.common.xml.SAMLSchemaBuilder; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.Status; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.ws.soap.soap11.Body; +import org.opensaml.ws.soap.soap11.Envelope; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.XMLObjectBuilderFactory; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.schema.XSString; +import org.opensaml.xml.schema.impl.XSStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +public class Saml2Utils { + private static final Logger log = LoggerFactory.getLogger(Saml2Utils.class); + + private static SecureRandomIdentifierGenerator idGenerator; + + private static DocumentBuilder builder; + + static { + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + + try { + builder = factory.newDocumentBuilder(); + + } catch (final ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + idGenerator = new SecureRandomIdentifierGenerator(); + + } catch (final NoSuchAlgorithmException e) { + e.printStackTrace(); + + } + } + + /** + * Create a SAML2 object. + * + * @param <T> SAML2 object class + * @param clazz object class + * @return SAML2 object + */ + public static <T> T createSamlObject(final Class<T> clazz) { + try { + final XMLObjectBuilderFactory builderFactory = + org.opensaml.xml.Configuration.getBuilderFactory(); + + final QName defaultElementName = + (QName) clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null); + @SuppressWarnings("unchecked") + final T object = + (T) builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName); + return object; + } catch (final Throwable e) { + e.printStackTrace(); + return null; + } + } + + /** + * Get a new SAML2 conform random value. + * + * @return + */ + public static String getSecureIdentifier() { + return "_".concat(Random.nextHexRandom16()); + + } + + + /** + * Transform SAML2 Object to Element. + * + * @param object SAML2 object + * @return Element + * @throws IOException In case of an transformation error + * @throws MarshallingException In case of an transformation error + * @throws TransformerException In case of an transformation error + */ + public static Document asDomDocument(final XMLObject object) + throws IOException, MarshallingException, TransformerException { + final Document document = builder.newDocument(); + final Marshaller out = + org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller(object); + out.marshall(object, document); + return document; + } + + /** + * Build success status element. + * + * @return + */ + public static Status getSuccessStatus() { + final Status status = Saml2Utils.createSamlObject(Status.class); + final StatusCode statusCode = Saml2Utils.createSamlObject(StatusCode.class); + statusCode.setValue(StatusCode.SUCCESS_URI); + status.setStatusCode(statusCode); + return status; + } + + /** + * Get AssertionConsumerService Index from metadata element. + * + * @param spSsoDescriptor metadata element + * @return + */ + public static int getDefaultAssertionConsumerServiceIndex(final SPSSODescriptor spSsoDescriptor) { + + final List<AssertionConsumerService> assertionConsumerList = + spSsoDescriptor.getAssertionConsumerServices(); + + for (final AssertionConsumerService el : assertionConsumerList) { + if (el.isDefault()) { + return el.getIndex(); + } + + } + + return 0; + } + + /** + * Build SOAP11 body from SAML2 object. + * + * @param payload SAML2 object + * @return + */ + public static Envelope buildSoap11Envelope(final XMLObject payload) { + final XMLObjectBuilderFactory bf = org.opensaml.xml.Configuration.getBuilderFactory(); + final Envelope envelope = (Envelope) bf.getBuilder(Envelope.DEFAULT_ELEMENT_NAME) + .buildObject(Envelope.DEFAULT_ELEMENT_NAME); + final Body body = + (Body) bf.getBuilder(Body.DEFAULT_ELEMENT_NAME).buildObject(Body.DEFAULT_ELEMENT_NAME); + + body.getUnknownXMLObjects().add(payload); + envelope.setBody(body); + + return envelope; + } + + /** + * Generate EAAF specific requested attribute. + * + * @param attr SAML2 attribute definition + * @param isRequired is-mandatory flag + * @param value Attribute value + * @return + */ + public static EaafRequestedAttribute generateReqAuthnAttributeSimple(final Attribute attr, + final boolean isRequired, final String value) { + final EaafRequestedAttribute requested = + Saml2Utils.createSamlObject(EaafRequestedAttribute.class); + requested.setName(attr.getName()); + requested.setNameFormat(attr.getNameFormat()); + requested.setFriendlyName(attr.getFriendlyName()); + requested.setIsRequired(String.valueOf(isRequired)); + final List<XMLObject> attributeValues = requested.getAttributeValues(); + if (StringUtils.isNotEmpty(value)) { + final XMLObject attributeValueForRequest = + createAttributeValue(PvpConstants.EIDAS_REQUESTED_ATTRIBUTE_VALUE_TYPE, value); + attributeValues.add(attributeValueForRequest); + } + return requested; + + } + + /** + * Perform XML schema-validation on SAML2 object. + * + * @param xmlObject SAML2 object + * @throws Exception In case of a validation error + */ + public static void schemeValidation(final XMLObject xmlObject) throws Exception { + try { + final Schema test = SAMLSchemaBuilder.getSAML11Schema(); + final Validator val = test.newValidator(); + final DOMSource source = new DOMSource(xmlObject.getDOM()); + val.validate(source); + log.debug("SAML2 Scheme validation successful"); + return; + + } catch (final Exception e) { + log.warn("SAML2 scheme validation FAILED.", e); + throw e; + + } + } + + private static XMLObject createAttributeValue(final QName attributeValueType, + final String value) { + final XSStringBuilder stringBuilder = (XSStringBuilder) org.opensaml.xml.Configuration + .getBuilderFactory().getBuilder(XSString.TYPE_NAME); + final XSString stringValue = stringBuilder.buildObject(attributeValueType, XSString.TYPE_NAME); + stringValue.setValue(value); + return stringValue; + + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/EAAFURICompare.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/EAAFURICompare.java deleted file mode 100644 index 30b7dcf9..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/EAAFURICompare.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.validation; - -import org.opensaml.common.binding.decoding.URIComparator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class EAAFURICompare implements URIComparator { - private static final Logger log = LoggerFactory.getLogger(EAAFURICompare.class); - - private String serviceURL = ""; - - /** - * - * - * @param serviceURL public URL of the PVP S-Profile endpoint - */ - public EAAFURICompare(String serviceURL) { - this.serviceURL = serviceURL; - } - - public boolean compare(String uri1, String uri2) { - if (this.serviceURL.equals(uri1)) - return true; - - else { - log.warn("PVP request destination-endpoint: " + uri1 - + " does not match to IDP endpoint:" + serviceURL); - return false; - - } - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/EaafUriCompare.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/EaafUriCompare.java new file mode 100644 index 00000000..fcee2382 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/EaafUriCompare.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.validation; + +import org.opensaml.common.binding.decoding.URIComparator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class EaafUriCompare implements URIComparator { + private static final Logger log = LoggerFactory.getLogger(EaafUriCompare.class); + + private String serviceUrl = ""; + + /** + * SAML2 URL comperator. + * + * @param serviceUrl public URL of the PVP S-Profile endpoint + */ + public EaafUriCompare(final String serviceUrl) { + this.serviceUrl = serviceUrl; + } + + @Override + public boolean compare(final String uri1, final String uri2) { + if (this.serviceUrl.equals(uri1)) { + return true; + } else { + log.warn("PVP request destination-endpoint: " + uri1 + " does not match to IDP endpoint:" + + serviceUrl); + return false; + + } + } + +} 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 18ee5797..d8ae95a0 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 @@ -1,34 +1,26 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.validation; import java.util.ArrayList; import java.util.List; - import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.security.MetadataCredentialResolver; import org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver; @@ -42,24 +34,31 @@ import org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine; public class TrustEngineFactory { - public static SignatureTrustEngine getSignatureKnownKeysTrustEngine(MetadataProvider provider) { - MetadataCredentialResolver resolver; + /** + * Get OpenSAML2 TrustEngine. + * + * @param provider Metadata provider + * @return + */ + public static SignatureTrustEngine getSignatureKnownKeysTrustEngine( + final MetadataProvider provider) { + MetadataCredentialResolver resolver; - resolver = new MetadataCredentialResolver(provider); + resolver = new MetadataCredentialResolver(provider); - List<KeyInfoProvider> keyInfoProvider = new ArrayList<KeyInfoProvider>(); - keyInfoProvider.add(new DSAKeyValueProvider()); - keyInfoProvider.add(new RSAKeyValueProvider()); - keyInfoProvider.add(new InlineX509DataProvider()); + final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>(); + keyInfoProvider.add(new DSAKeyValueProvider()); + keyInfoProvider.add(new RSAKeyValueProvider()); + keyInfoProvider.add(new InlineX509DataProvider()); - KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( - keyInfoProvider); + final KeyInfoCredentialResolver keyInfoResolver = + new BasicProviderKeyInfoCredentialResolver(keyInfoProvider); - ExplicitKeySignatureTrustEngine engine = new ExplicitKeySignatureTrustEngine( - resolver, keyInfoResolver); + final ExplicitKeySignatureTrustEngine engine = + new ExplicitKeySignatureTrustEngine(resolver, keyInfoResolver); - return engine; + return engine; - } + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/AbstractMetadataSignatureFilter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/AbstractMetadataSignatureFilter.java index 424c4431..40cbdeb0 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/AbstractMetadataSignatureFilter.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/AbstractMetadataSignatureFilter.java @@ -1,35 +1,30 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata; import java.util.ArrayList; import java.util.Iterator; import java.util.List; - +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SignatureValidationException; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.provider.MetadataFilter; @@ -37,118 +32,117 @@ import org.opensaml.xml.XMLObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2MetadataException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SignatureValidationException; - public abstract class AbstractMetadataSignatureFilter implements MetadataFilter { - private static final Logger log = LoggerFactory.getLogger(AbstractMetadataSignatureFilter.class); - - public void doFilter(XMLObject metadata) throws SignatureValidationException { - try { - if (metadata instanceof EntitiesDescriptor) { - EntitiesDescriptor entitiesDescriptor = (EntitiesDescriptor) metadata; - if(entitiesDescriptor.getSignature() == null) { - throw new PVP2MetadataException("pvp2.26", - new Object[] {"Root element of metadata file has to be signed"}); - } - processEntitiesDescriptor(entitiesDescriptor); - - - if (entitiesDescriptor.getEntityDescriptors().size() == 0) { - throw new PVP2MetadataException("pvp2.26", - new Object[] {"No valid entity in metadata " + entitiesDescriptor.getName()}); - } - - - } else if (metadata instanceof EntityDescriptor) { - EntityDescriptor entityDescriptor = (EntityDescriptor) metadata; - processEntityDescriptorr(entityDescriptor); - - } else - throw new PVP2MetadataException("pvp2.26", - new Object[] {"Invalid Metadata file Root element is unknown"}); - - - - log.info("Metadata signature policy check done OK"); - } catch (EAAFException e) { - log.warn("Metadata signature policy check FAILED.", e); - throw new SignatureValidationException(e); - - } - } - - /** - * Signature verification of a SAML2 EntityDescriptor element - * - * @param desc - * @throws PVP2MetadataException if the signature is not valid or can not verified - */ - protected abstract void verify(EntityDescriptor desc) throws PVP2MetadataException; - - /** - * Signature verification of a SAML2 EntitiesDescriptor element - * - * @param desc - * @throws PVP2MetadataException if the signature is not valid or can not verified - */ - protected abstract void verify(EntitiesDescriptor desc) throws PVP2MetadataException; - - /** - * Verify a EntityDescriptor element of an EntitiesDescriptor - * - * @param entity EntityDescriptor to verify - * @param desc Full EntitiesDescriptor that contains the EntityDescriptor - * @throws PVP2MetadataException - */ - protected abstract void verify(EntityDescriptor entity, EntitiesDescriptor desc) throws PVP2MetadataException; - - - private void processEntityDescriptorr(EntityDescriptor desc) throws EAAFException { - verify(desc); - - } - - private void processEntitiesDescriptor(EntitiesDescriptor desc) throws EAAFException { - Iterator<EntitiesDescriptor> entID = desc.getEntitiesDescriptors().iterator(); - - if(desc.getSignature() != null) { - verify(desc); - - } - - while(entID.hasNext()) { - processEntitiesDescriptor(entID.next()); - } - - Iterator<EntityDescriptor> entIT = desc.getEntityDescriptors().iterator(); - List<EntityDescriptor> verifiedEntIT = new ArrayList<EntityDescriptor>(); - - //check every Entity - while(entIT.hasNext()) { - EntityDescriptor entity = entIT.next(); - log.debug("Validate metadata for entityID: " + entity.getEntityID() + " ..... "); - try { - verify(entity, desc); - - //add entity to verified entity-list - verifiedEntIT.add(entity); - log.debug("Metadata for entityID: " + entity.getEntityID() + " valid"); - - - } catch (Exception e) { - //remove entity of signature can not be verified. - log.info("Entity " + entity.getEntityID() + " is removed from metadata " - + desc.getName() + ". Entity verification error: " + e.getMessage()); - - } - - } - - //set only verified entity elements - desc.getEntityDescriptors().clear(); - desc.getEntityDescriptors().addAll(verifiedEntIT); - } + private static final Logger log = LoggerFactory.getLogger(AbstractMetadataSignatureFilter.class); + + @Override + public void doFilter(final XMLObject metadata) throws SignatureValidationException { + try { + if (metadata instanceof EntitiesDescriptor) { + final EntitiesDescriptor entitiesDescriptor = (EntitiesDescriptor) metadata; + if (entitiesDescriptor.getSignature() == null) { + throw new Pvp2MetadataException("pvp2.26", + new Object[] {"Root element of metadata file has to be signed"}); + } + processEntitiesDescriptor(entitiesDescriptor); + + + if (entitiesDescriptor.getEntityDescriptors().size() == 0) { + throw new Pvp2MetadataException("pvp2.26", + new Object[] {"No valid entity in metadata " + entitiesDescriptor.getName()}); + } + + + } else if (metadata instanceof EntityDescriptor) { + final EntityDescriptor entityDescriptor = (EntityDescriptor) metadata; + processEntityDescriptorr(entityDescriptor); + + } else { + throw new Pvp2MetadataException("pvp2.26", + new Object[] {"Invalid Metadata file Root element is unknown"}); + } + + + + log.info("Metadata signature policy check done OK"); + } catch (final EaafException e) { + log.warn("Metadata signature policy check FAILED.", e); + throw new SignatureValidationException(e); + + } + } + + /** + * Signature verification of a SAML2 EntityDescriptor element. + * + * @param desc EntityDescriptor + * @throws Pvp2MetadataException if the signature is not valid or can not verified + */ + protected abstract void verify(EntityDescriptor desc) throws Pvp2MetadataException; + + /** + * Signature verification of a SAML2 EntitiesDescriptor element. + * + * @param desc EntitiesDescriptor + * @throws Pvp2MetadataException if the signature is not valid or can not verified + */ + protected abstract void verify(EntitiesDescriptor desc) throws Pvp2MetadataException; + + /** + * Verify a EntityDescriptor element of an EntitiesDescriptor. + * + * @param entity EntityDescriptor to verify + * @param desc Full EntitiesDescriptor that contains the EntityDescriptor + * @throws Pvp2MetadataException In case of an verification error + */ + protected abstract void verify(EntityDescriptor entity, EntitiesDescriptor desc) + throws Pvp2MetadataException; + + + private void processEntityDescriptorr(final EntityDescriptor desc) throws EaafException { + verify(desc); + + } + + private void processEntitiesDescriptor(final EntitiesDescriptor desc) throws EaafException { + final Iterator<EntitiesDescriptor> entID = desc.getEntitiesDescriptors().iterator(); + + if (desc.getSignature() != null) { + verify(desc); + + } + + while (entID.hasNext()) { + processEntitiesDescriptor(entID.next()); + } + + final Iterator<EntityDescriptor> entIT = desc.getEntityDescriptors().iterator(); + final List<EntityDescriptor> verifiedEntIT = new ArrayList<>(); + + // check every Entity + while (entIT.hasNext()) { + final EntityDescriptor entity = entIT.next(); + log.debug("Validate metadata for entityID: " + entity.getEntityID() + " ..... "); + try { + verify(entity, desc); + + // add entity to verified entity-list + verifiedEntIT.add(entity); + log.debug("Metadata for entityID: " + entity.getEntityID() + " valid"); + + + } catch (final Exception e) { + // remove entity of signature can not be verified. + log.info("Entity " + entity.getEntityID() + " is removed from metadata " + desc.getName() + + ". Entity verification error: " + e.getMessage()); + + } + + } + + // set only verified entity elements + desc.getEntityDescriptors().clear(); + desc.getEntityDescriptors().addAll(verifiedEntIT); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PVPEntityCategoryFilter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PVPEntityCategoryFilter.java deleted file mode 100644 index 87ab31fb..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PVPEntityCategoryFilter.java +++ /dev/null @@ -1,236 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata; - -import java.util.ArrayList; -import java.util.List; - -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.common.Extensions; -import org.opensaml.saml2.core.Attribute; -import org.opensaml.saml2.metadata.AttributeConsumingService; -import org.opensaml.saml2.metadata.EntitiesDescriptor; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.LocalizedString; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.opensaml.saml2.metadata.ServiceName; -import org.opensaml.saml2.metadata.provider.FilterException; -import org.opensaml.saml2.metadata.provider.MetadataFilter; -import org.opensaml.samlext.saml2mdattr.EntityAttributes; -import org.opensaml.xml.XMLObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.eaaf.core.impl.data.Trible; -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2MetadataException; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPAttributeBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - -/** - * @author tlenz - * - */ -public class PVPEntityCategoryFilter implements MetadataFilter { - private static final Logger log = LoggerFactory.getLogger(PVPEntityCategoryFilter.class); - - private boolean isUsed = false; - - /** - * Filter to map PVP EntityCategories into a set of single PVP attributes - * - * @param isUsed if true PVP EntityCategories are mapped, otherwise they are ignored - * - */ - public PVPEntityCategoryFilter(boolean isUsed) { - this.isUsed = isUsed; - } - - - /* (non-Javadoc) - * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) - */ - @Override - public void doFilter(XMLObject metadata) throws FilterException { - - if (isUsed) { - log.trace("Map PVP EntityCategory to single PVP Attributes ... "); - String entityId = null; - try { - if (metadata instanceof EntitiesDescriptor) { - log.trace("Find EnitiesDescriptor ... "); - EntitiesDescriptor entitiesDesc = (EntitiesDescriptor) metadata; - if (entitiesDesc.getEntityDescriptors() != null) { - for (EntityDescriptor el : entitiesDesc.getEntityDescriptors()) - resolveEntityCategoriesToAttributes(el); - - } - - } else if (metadata instanceof EntityDescriptor) { - log.trace("Find EntityDescriptor"); - resolveEntityCategoriesToAttributes((EntityDescriptor)metadata); - - - } else - throw new PVP2MetadataException("pvp2.26", - new Object[] {"Invalid Metadata file Root element is no Entities- or EntityDescriptor"}); - - - - } catch (Exception e) { - log.warn("SAML2 Metadata processing FAILED: Can not resolve EntityCategories for metadata: " + entityId, e); - - } - - } else - log.trace("Filter to map PVP EntityCategory to single PVP Attributes is deactivated"); - - } - - private void resolveEntityCategoriesToAttributes(EntityDescriptor metadata) { - log.debug("Resolving EntityCategorie for Entity: " + metadata.getEntityID() + " ..."); - Extensions extensions = metadata.getExtensions(); - if (extensions != null) { - List<XMLObject> listOfExt = extensions.getUnknownXMLObjects(); - if (listOfExt != null && !listOfExt.isEmpty()) { - log.trace("Find #" + listOfExt.size() + " 'Extension' elements "); - for (XMLObject el : listOfExt) { - log.trace("Find ExtensionElement: " + el.getElementQName().toString()); - if (el instanceof EntityAttributes) { - EntityAttributes entityAttrElem = (EntityAttributes)el; - if (entityAttrElem.getAttributes() != null) { - log.trace("Find EntityAttributes. Start attribute processing ..."); - for (Attribute entityAttr : entityAttrElem.getAttributes()) { - if (entityAttr.getName().equals(PVPConstants.ENTITY_CATEGORY_ATTRIBITE)) { - if (!entityAttr.getAttributeValues().isEmpty()) { - String entityAttrValue = entityAttr.getAttributeValues().get(0).getDOM().getTextContent(); - if (PVPConstants.EGOVTOKEN.equals(entityAttrValue)) { - log.debug("Find 'EGOVTOKEN' EntityAttribute. Adding single pvp attributes ... "); - addAttributesToEntityDescriptor(metadata, - buildAttributeList(PVPConstants.EGOVTOKEN_PVP_ATTRIBUTES), - entityAttrValue); - - - } else if (PVPConstants.CITIZENTOKEN.equals(entityAttrValue)) { - log.debug("Find 'CITIZENTOKEN' EntityAttribute. Adding single pvp attributes ... "); - addAttributesToEntityDescriptor(metadata, - buildAttributeList(PVPConstants.CITIZENTOKEN_PVP_ATTRIBUTES), - entityAttrValue); - - } else - log.info("EntityAttributeValue: " + entityAttrValue + " is UNKNOWN!"); - - } else - log.info("EntityAttribute: No attribute value"); - - } else - log.info("EntityAttribute: " + entityAttr.getName() + " is NOT supported"); - - } - - } else - log.info("Can NOT resolve EntityAttributes! Reason: Only EntityAttributes are supported!"); - - } - } - - } else - log.trace("'Extension' element is 'null' or empty"); - - } else - log.trace("No 'Extension' element found"); - - } - - /** - * @param metadata - * @param attrList - */ - private void addAttributesToEntityDescriptor(EntityDescriptor metadata, List<RequestedAttribute> attrList, String entityAttr) { - SPSSODescriptor spSSODesc = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); - if (spSSODesc != null) { - if (spSSODesc.getAttributeConsumingServices() == null || - spSSODesc.getAttributeConsumingServices().isEmpty()) { - log.trace("No 'AttributeConsumingServices' found. Added it ..."); - - AttributeConsumingService attributeService = SAML2Utils.createSAMLObject(AttributeConsumingService.class); - attributeService.setIndex(0); - attributeService.setIsDefault(true); - ServiceName serviceName = SAML2Utils.createSAMLObject(ServiceName.class); - serviceName.setName(new LocalizedString("Default Service", "en")); - attributeService.getNames().add(serviceName); - - if (attrList != null && !attrList.isEmpty()) { - attributeService.getRequestAttributes().addAll(attrList); - log.info("Add " + attrList.size() + " attributes for 'EntityAttribute': " + entityAttr); - - } - - spSSODesc.getAttributeConsumingServices().add(attributeService); - - } else { - log.debug("Find 'AttributeConsumingServices'. Starting updating process ... "); - for (AttributeConsumingService el : spSSODesc.getAttributeConsumingServices()) { - log.debug("Update 'AttributeConsumingService' with Index: " + el.getIndex()); - - //load currently requested attributes - List<String> currentlyReqAttr = new ArrayList<String>(); - for (RequestedAttribute reqAttr : el.getRequestAttributes()) - currentlyReqAttr.add(reqAttr.getName()); - - - //check against EntityAttribute List - for (RequestedAttribute entityAttrListEl : attrList) { - if (!currentlyReqAttr.contains(entityAttrListEl.getName())) { - el.getRequestAttributes().add(entityAttrListEl); - - } else - log.debug("'AttributeConsumingService' already contains attr: " + entityAttrListEl.getName()); - - } - - } - - } - - } else - log.info("Can ONLY add 'EntityAttributes' to 'SPSSODescriptor'"); - - } - - private List<RequestedAttribute> buildAttributeList(List<Trible<String, String, Boolean>> attrSet) { - List<RequestedAttribute> requestedAttributes = new ArrayList<RequestedAttribute>(); - for (Trible<String, String, Boolean> el : attrSet) - requestedAttributes.add(PVPAttributeBuilder.buildReqAttribute(el.getFirst(), el.getSecond(), el.getThird())); - - return requestedAttributes; - - - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java new file mode 100644 index 00000000..2d81b1f8 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/PvpEntityCategoryFilter.java @@ -0,0 +1,251 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata; + +import java.util.ArrayList; +import java.util.List; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.common.Extensions; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.metadata.AttributeConsumingService; +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.LocalizedString; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.ServiceName; +import org.opensaml.saml2.metadata.provider.FilterException; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.samlext.saml2mdattr.EntityAttributes; +import org.opensaml.xml.XMLObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Metadata filter that inject requested attributes based on Metadata EntityCategories. + * + * @author tlenz + * + */ +public class PvpEntityCategoryFilter implements MetadataFilter { + private static final Logger log = LoggerFactory.getLogger(PvpEntityCategoryFilter.class); + + private boolean isUsed = false; + + /** + * Filter to map PVP EntityCategories into a set of single PVP attributes. + * + * @param isUsed if true PVP EntityCategories are mapped, otherwise they are ignored + * + */ + public PvpEntityCategoryFilter(final boolean isUsed) { + this.isUsed = isUsed; + } + + + /* + * (non-Javadoc) + * + * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) + */ + @Override + public void doFilter(final XMLObject metadata) throws FilterException { + + if (isUsed) { + log.trace("Map PVP EntityCategory to single PVP Attributes ... "); + final String entityId = null; + try { + if (metadata instanceof EntitiesDescriptor) { + log.trace("Find EnitiesDescriptor ... "); + final EntitiesDescriptor entitiesDesc = (EntitiesDescriptor) metadata; + if (entitiesDesc.getEntityDescriptors() != null) { + for (final EntityDescriptor el : entitiesDesc.getEntityDescriptors()) { + resolveEntityCategoriesToAttributes(el); + } + + } + + } else if (metadata instanceof EntityDescriptor) { + log.trace("Find EntityDescriptor"); + resolveEntityCategoriesToAttributes((EntityDescriptor) metadata); + + + } else { + throw new Pvp2MetadataException("pvp2.26", new Object[] { + "Invalid Metadata file Root element is no Entities- or EntityDescriptor"}); + } + + + + } catch (final Exception e) { + log.warn("SAML2 Metadata processing FAILED: Can not resolve EntityCategories for metadata: " + + entityId, e); + + } + + } else { + log.trace("Filter to map PVP EntityCategory to single PVP Attributes is deactivated"); + } + + } + + private void resolveEntityCategoriesToAttributes(final EntityDescriptor metadata) { + log.debug("Resolving EntityCategorie for Entity: " + metadata.getEntityID() + " ..."); + final Extensions extensions = metadata.getExtensions(); + if (extensions != null) { + final List<XMLObject> listOfExt = extensions.getUnknownXMLObjects(); + if (listOfExt != null && !listOfExt.isEmpty()) { + log.trace("Find #" + listOfExt.size() + " 'Extension' elements "); + for (final XMLObject el : listOfExt) { + log.trace("Find ExtensionElement: " + el.getElementQName().toString()); + if (el instanceof EntityAttributes) { + final EntityAttributes entityAttrElem = (EntityAttributes) el; + if (entityAttrElem.getAttributes() != null) { + log.trace("Find EntityAttributes. Start attribute processing ..."); + for (final Attribute entityAttr : entityAttrElem.getAttributes()) { + if (entityAttr.getName().equals(PvpConstants.ENTITY_CATEGORY_ATTRIBITE)) { + if (!entityAttr.getAttributeValues().isEmpty()) { + final String entityAttrValue = + entityAttr.getAttributeValues().get(0).getDOM().getTextContent(); + if (PvpConstants.EGOVTOKEN.equals(entityAttrValue)) { + log.debug( + "Find 'EGOVTOKEN' EntityAttribute. Adding single pvp attributes ... "); + addAttributesToEntityDescriptor(metadata, + buildAttributeList(PvpConstants.EGOVTOKEN_PVP_ATTRIBUTES), + entityAttrValue); + + + } else if (PvpConstants.CITIZENTOKEN.equals(entityAttrValue)) { + log.debug( + "Find 'CITIZENTOKEN' EntityAttribute. Adding single pvp attributes ... "); + addAttributesToEntityDescriptor(metadata, + buildAttributeList(PvpConstants.CITIZENTOKEN_PVP_ATTRIBUTES), + entityAttrValue); + + } else { + log.info("EntityAttributeValue: " + entityAttrValue + " is UNKNOWN!"); + } + + } else { + log.info("EntityAttribute: No attribute value"); + } + + } else { + log.info("EntityAttribute: " + entityAttr.getName() + " is NOT supported"); + } + + } + + } else { + log.info( + "Can NOT resolve EntityAttributes! Reason: Only EntityAttributes are supported!"); + } + + } + } + + } else { + log.trace("'Extension' element is 'null' or empty"); + } + + } else { + log.trace("No 'Extension' element found"); + } + + } + + + private void addAttributesToEntityDescriptor(final EntityDescriptor metadata, + final List<RequestedAttribute> attrList, final String entityAttr) { + final SPSSODescriptor spSsoDesc = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); + if (spSsoDesc != null) { + if (spSsoDesc.getAttributeConsumingServices() == null + || spSsoDesc.getAttributeConsumingServices().isEmpty()) { + log.trace("No 'AttributeConsumingServices' found. Added it ..."); + + final AttributeConsumingService attributeService = + Saml2Utils.createSamlObject(AttributeConsumingService.class); + attributeService.setIndex(0); + attributeService.setIsDefault(true); + final ServiceName serviceName = Saml2Utils.createSamlObject(ServiceName.class); + serviceName.setName(new LocalizedString("Default Service", "en")); + attributeService.getNames().add(serviceName); + + if (attrList != null && !attrList.isEmpty()) { + attributeService.getRequestAttributes().addAll(attrList); + log.info("Add " + attrList.size() + " attributes for 'EntityAttribute': " + entityAttr); + + } + + spSsoDesc.getAttributeConsumingServices().add(attributeService); + + } else { + log.debug("Find 'AttributeConsumingServices'. Starting updating process ... "); + for (final AttributeConsumingService el : spSsoDesc.getAttributeConsumingServices()) { + log.debug("Update 'AttributeConsumingService' with Index: " + el.getIndex()); + + // load currently requested attributes + final List<String> currentlyReqAttr = new ArrayList<>(); + for (final RequestedAttribute reqAttr : el.getRequestAttributes()) { + currentlyReqAttr.add(reqAttr.getName()); + } + + + // check against EntityAttribute List + for (final RequestedAttribute entityAttrListEl : attrList) { + if (!currentlyReqAttr.contains(entityAttrListEl.getName())) { + el.getRequestAttributes().add(entityAttrListEl); + + } else { + log.debug("'AttributeConsumingService' already contains attr: " + + entityAttrListEl.getName()); + } + + } + + } + + } + + } else { + log.info("Can ONLY add 'EntityAttributes' to 'SPSSODescriptor'"); + } + + } + + private List<RequestedAttribute> buildAttributeList( + final List<Trible<String, String, Boolean>> attrSet) { + final List<RequestedAttribute> requestedAttributes = new ArrayList<>(); + for (final Trible<String, String, Boolean> el : attrSet) { + requestedAttributes + .add(PvpAttributeBuilder.buildReqAttribute(el.getFirst(), el.getSecond(), el.getThird())); + } + + return requestedAttributes; + + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/SchemaValidationFilter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/SchemaValidationFilter.java index b5de4b21..3ff78ca8 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/SchemaValidationFilter.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/validation/metadata/SchemaValidationFilter.java @@ -1,35 +1,28 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.Validator; - +import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; import org.opensaml.common.xml.SAMLSchemaBuilder; import org.opensaml.saml2.metadata.provider.FilterException; import org.opensaml.saml2.metadata.provider.MetadataFilter; @@ -38,69 +31,65 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; - -/** - * @author tlenz - * - */ public class SchemaValidationFilter implements MetadataFilter { - private static final Logger log = LoggerFactory.getLogger(SchemaValidationFilter.class); - private boolean isActive = true; - - public SchemaValidationFilter() { - } - - /** - * - */ - public SchemaValidationFilter(boolean useSchemaValidation) { - this.isActive = useSchemaValidation; - } - - - /* (non-Javadoc) - * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) - */ - @Override - public void doFilter(XMLObject arg0) throws FilterException { - - String errString = null; - - if (isActive) { - try { - Schema test = SAMLSchemaBuilder.getSAML11Schema(); - Validator val = test.newValidator(); - DOMSource source = new DOMSource(arg0.getDOM()); - val.validate(source); - log.info("Metadata Schema validation check done OK"); - return; - - } catch (SAXException e) { - if (log.isDebugEnabled() || log.isTraceEnabled()) - log.warn("Metadata Schema validation FAILED with exception:", e); - else - log.warn("Metadata Schema validation FAILED with message: "+ e.getMessage()); - - errString = e.getMessage(); - - } catch (Exception e) { - if (log.isDebugEnabled() || log.isTraceEnabled()) - log.warn("Metadata Schema validation FAILED with exception:", e); - else - log.warn("Metadata Schema validation FAILED with message: "+ e.getMessage()); - - errString = e.getMessage(); - - } - - throw new FilterException( - new SchemaValidationException("pvp2.26", - new Object[] {"Metadata Schema validation FAILED with message: " + errString})); - - } else - log.info("Metadata Schema validation check is DEACTIVATED!"); - - } + private static final Logger log = LoggerFactory.getLogger(SchemaValidationFilter.class); + private boolean isActive = true; + + public SchemaValidationFilter() { + + } + + public SchemaValidationFilter(final boolean useSchemaValidation) { + this.isActive = useSchemaValidation; + } + + + /* + * (non-Javadoc) + * + * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) + */ + @Override + public void doFilter(final XMLObject arg0) throws FilterException { + + String errString = null; + + if (isActive) { + try { + final Schema test = SAMLSchemaBuilder.getSAML11Schema(); + final Validator val = test.newValidator(); + final DOMSource source = new DOMSource(arg0.getDOM()); + val.validate(source); + log.info("Metadata Schema validation check done OK"); + return; + + } catch (final SAXException e) { + if (log.isDebugEnabled() || log.isTraceEnabled()) { + log.warn("Metadata Schema validation FAILED with exception:", e); + } else { + log.warn("Metadata Schema validation FAILED with message: " + e.getMessage()); + } + + errString = e.getMessage(); + + } catch (final Exception e) { + if (log.isDebugEnabled() || log.isTraceEnabled()) { + log.warn("Metadata Schema validation FAILED with exception:", e); + } else { + log.warn("Metadata Schema validation FAILED with message: " + e.getMessage()); + } + + errString = e.getMessage(); + + } + + throw new FilterException(new SchemaValidationException("pvp2.26", + new Object[] {"Metadata Schema validation FAILED with message: " + errString})); + + } else { + log.info("Metadata Schema validation check is DEACTIVATED!"); + } + + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/AbstractRequestSignedSecurityPolicyRule.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/AbstractRequestSignedSecurityPolicyRule.java index f1dd1269..fc1b6ea8 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/AbstractRequestSignedSecurityPolicyRule.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/AbstractRequestSignedSecurityPolicyRule.java @@ -1,36 +1,29 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.verification; import javax.xml.namespace.QName; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.Validator; - +import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; import org.apache.commons.lang3.StringUtils; import org.opensaml.common.SignableSAMLObject; import org.opensaml.common.xml.SAMLConstants; @@ -52,144 +45,154 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.xml.sax.SAXException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException; - /** + * Signature Policy for SAML2 redirect-binding. + * * @author tlenz * */ public abstract class AbstractRequestSignedSecurityPolicyRule implements SecurityPolicyRule { - private static final Logger log = LoggerFactory.getLogger(AbstractRequestSignedSecurityPolicyRule.class); - - - private SignatureTrustEngine trustEngine = null; - private QName peerEntityRole = null; - /** - * @param peerEntityRole - * - */ - public AbstractRequestSignedSecurityPolicyRule(SignatureTrustEngine trustEngine, QName peerEntityRole) { - this.trustEngine = trustEngine; - this.peerEntityRole = peerEntityRole; - - } - - - /** - * Reload the PVP metadata for a given entity - * - * @param entityID for which the metadata should be refreshed. - * @return true if the refresh was successful, otherwise false - */ - protected abstract boolean refreshMetadataProvider(String entityID); - - - protected abstract SignableSAMLObject getSignedSAMLObject(XMLObject inboundData); - - /* (non-Javadoc) - * @see org.opensaml.ws.security.SecurityPolicyRule#evaluate(org.opensaml.ws.message.MessageContext) - */ - @Override - public void evaluate(MessageContext context) throws SecurityPolicyException { - try { - verifySignature(context); - - } catch (SecurityPolicyException e) { - if (StringUtils.isEmpty(context.getInboundMessageIssuer())) { - throw e; - - } - log.debug("PVP2X message validation FAILED. Reload metadata for entityID: " + context.getInboundMessageIssuer()); - if (!refreshMetadataProvider(context.getInboundMessageIssuer())) - throw e; - - else { - log.trace("PVP2X metadata reload finished. Check validate message again."); - verifySignature(context); - - } - log.trace("Second PVP2X message validation finished"); - - } - - - } - - private void verifySignature(MessageContext context) throws SecurityPolicyException { - SignableSAMLObject samlObj = getSignedSAMLObject(context.getInboundMessage()); - if (samlObj != null && samlObj.getSignature() != null) { - - SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); - try { - profileValidator.validate(samlObj.getSignature()); - performSchemaValidation(samlObj.getDOM()); - - } catch (ValidationException e) { - log.warn("Signature is not conform to SAML signature profile", e); - throw new SecurityPolicyException("Signature is not conform to SAML signature profile"); - - } catch (SchemaValidationException e) { - log.warn("Signature is not conform to SAML signature profile", e); - throw new SecurityPolicyException("Signature is not conform to SAML signature profile"); - - } - - - - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add( new EntityIDCriteria(context.getInboundMessageIssuer()) ); - criteriaSet.add( new MetadataCriteria(peerEntityRole, SAMLConstants.SAML20P_NS) ); - criteriaSet.add( new UsageCriteria(UsageType.SIGNING) ); - - try { - if (!trustEngine.validate(samlObj.getSignature(), criteriaSet)) { - throw new SecurityPolicyException("Signature validation FAILED."); - - } - log.debug("PVP message signature valid."); - - } catch (org.opensaml.xml.security.SecurityException e) { - log.info("PVP2x message signature validation FAILED. Message:" + e.getMessage()); - throw new SecurityPolicyException("Signature validation FAILED."); - - } - - } else { - throw new SecurityPolicyException("PVP Message is not signed."); - - } - - } - - private void performSchemaValidation(Element source) throws SchemaValidationException { - - String err = null; - try { - Schema test = SAMLSchemaBuilder.getSAML11Schema(); - Validator val = test.newValidator(); - val.validate(new DOMSource(source)); - log.debug("Schema validation check done OK"); - return; - - } catch (SAXException e) { - err = e.getMessage(); - if (log.isDebugEnabled() || log.isTraceEnabled()) - log.warn("Schema validation FAILED with exception:", e); - else - log.warn("Schema validation FAILED with message: "+ e.getMessage()); - - } catch (Exception e) { - err = e.getMessage(); - if (log.isDebugEnabled() || log.isTraceEnabled()) - log.warn("Schema validation FAILED with exception:", e); - else - log.warn("Schema validation FAILED with message: "+ e.getMessage()); - - } - - throw new SchemaValidationException("pvp2.22", new Object[]{err}); - - } + private static final Logger log = + LoggerFactory.getLogger(AbstractRequestSignedSecurityPolicyRule.class); + + + private SignatureTrustEngine trustEngine = null; + private QName peerEntityRole = null; + + /** + * Role initializer. + * + * @param peerEntityRole + * + */ + public AbstractRequestSignedSecurityPolicyRule(final SignatureTrustEngine trustEngine, + final QName peerEntityRole) { + this.trustEngine = trustEngine; + this.peerEntityRole = peerEntityRole; + + } + + + /** + * Reload the PVP metadata for a given entity. + * + * @param entityID for which the metadata should be refreshed. + * @return true if the refresh was successful, otherwise false + */ + protected abstract boolean refreshMetadataProvider(String entityID); + + + protected abstract SignableSAMLObject getSignedSamlObject(XMLObject inboundData); + + /* + * (non-Javadoc) + * + * @see + * org.opensaml.ws.security.SecurityPolicyRule#evaluate(org.opensaml.ws.message.MessageContext) + */ + @Override + public void evaluate(final MessageContext context) throws SecurityPolicyException { + try { + verifySignature(context); + + } catch (final SecurityPolicyException e) { + if (StringUtils.isEmpty(context.getInboundMessageIssuer())) { + throw e; + + } + log.debug("PVP2X message validation FAILED. Reload metadata for entityID: " + + context.getInboundMessageIssuer()); + if (!refreshMetadataProvider(context.getInboundMessageIssuer())) { + throw e; + } else { + log.trace("PVP2X metadata reload finished. Check validate message again."); + verifySignature(context); + + } + log.trace("Second PVP2X message validation finished"); + + } + + + } + + private void verifySignature(final MessageContext context) throws SecurityPolicyException { + final SignableSAMLObject samlObj = getSignedSamlObject(context.getInboundMessage()); + if (samlObj != null && samlObj.getSignature() != null) { + + final SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); + try { + profileValidator.validate(samlObj.getSignature()); + performSchemaValidation(samlObj.getDOM()); + + } catch (final ValidationException e) { + log.warn("Signature is not conform to SAML signature profile", e); + throw new SecurityPolicyException("Signature is not conform to SAML signature profile"); + + } catch (final SchemaValidationException e) { + log.warn("Signature is not conform to SAML signature profile", e); + throw new SecurityPolicyException("Signature is not conform to SAML signature profile"); + + } + + + + final CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new EntityIDCriteria(context.getInboundMessageIssuer())); + criteriaSet.add(new MetadataCriteria(peerEntityRole, SAMLConstants.SAML20P_NS)); + criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); + + try { + if (!trustEngine.validate(samlObj.getSignature(), criteriaSet)) { + throw new SecurityPolicyException("Signature validation FAILED."); + + } + log.debug("PVP message signature valid."); + + } catch (final org.opensaml.xml.security.SecurityException e) { + log.info("PVP2x message signature validation FAILED. Message:" + e.getMessage()); + throw new SecurityPolicyException("Signature validation FAILED."); + + } + + } else { + throw new SecurityPolicyException("PVP Message is not signed."); + + } + + } + + private void performSchemaValidation(final Element source) throws SchemaValidationException { + + String err = null; + try { + final Schema test = SAMLSchemaBuilder.getSAML11Schema(); + final Validator val = test.newValidator(); + val.validate(new DOMSource(source)); + log.debug("Schema validation check done OK"); + return; + + } catch (final SAXException e) { + err = e.getMessage(); + if (log.isDebugEnabled() || log.isTraceEnabled()) { + log.warn("Schema validation FAILED with exception:", e); + } else { + log.warn("Schema validation FAILED with message: " + e.getMessage()); + } + + } catch (final Exception e) { + err = e.getMessage(); + if (log.isDebugEnabled() || log.isTraceEnabled()) { + log.warn("Schema validation FAILED with exception:", e); + } else { + log.warn("Schema validation FAILED with message: " + e.getMessage()); + } + + } + + throw new SchemaValidationException("pvp2.22", new Object[] {err}); + + } } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PVPAuthRequestSignedRole.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PVPAuthRequestSignedRole.java deleted file mode 100644 index 6d5fdff8..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PVPAuthRequestSignedRole.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.verification; - -import java.util.List; - -import org.opensaml.common.binding.SAMLMessageContext; -import org.opensaml.saml2.binding.security.SAML2AuthnRequestsSignedRule; -import org.opensaml.ws.transport.http.HTTPInTransport; -import org.opensaml.xml.util.DatatypeHelper; - -/** - * @author tlenz - * - */ -public class PVPAuthRequestSignedRole extends SAML2AuthnRequestsSignedRule { - - @Override - protected boolean isMessageSigned(SAMLMessageContext messageContext) { - // This handles HTTP-Redirect and HTTP-POST-SimpleSign bindings. - HTTPInTransport inTransport = (HTTPInTransport) messageContext.getInboundMessageTransport(); - - //Check signature parameter exists only once and is not empty - List<String> sigParam = inTransport.getParameterValues("Signature"); - boolean isValidSigned = sigParam.size() == 1 && !DatatypeHelper.isEmpty(sigParam.get(0)); - - //Check signature-algorithm parameter exists only once and is not empty - List<String> sigAlgParam = inTransport.getParameterValues("SigAlg"); - boolean isValidSigAlgExists = sigAlgParam.size() == 1 && !DatatypeHelper.isEmpty(sigAlgParam.get(0)); - - //Check signature-content parameter exists only once and is not empty - List<String> samlReqParam = inTransport.getParameterValues("SAMLRequest"); - List<String> samlRespParam = inTransport.getParameterValues("SAMLResponse"); - boolean isValidContent = ( ( samlReqParam.size() == 1 && !DatatypeHelper.isEmpty(samlReqParam.get(0)) ) - || ( samlRespParam.size() == 1 && !DatatypeHelper.isEmpty(samlRespParam.get(0)) ) - ) && !(samlReqParam.size() == 1 && samlRespParam.size() == 1) - ; - - return isValidSigned && isValidSigAlgExists && isValidContent; - - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PVPSignedRequestPolicyRule.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PVPSignedRequestPolicyRule.java deleted file mode 100644 index eecaf4f0..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PVPSignedRequestPolicyRule.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.verification; - -import javax.xml.namespace.QName; - -import org.opensaml.common.SignableSAMLObject; -import org.opensaml.saml2.metadata.provider.MetadataProvider; -import org.opensaml.xml.XMLObject; -import org.opensaml.xml.signature.SignatureTrustEngine; - -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; - -/** - * @author tlenz - * - */ -public class PVPSignedRequestPolicyRule extends - AbstractRequestSignedSecurityPolicyRule { - - private IRefreshableMetadataProvider metadataProvider = null; - - /** - * @param metadataProvider - * @param trustEngine - * @param peerEntityRole - */ - public PVPSignedRequestPolicyRule(MetadataProvider metadataProvider, SignatureTrustEngine trustEngine, - QName peerEntityRole) { - super(trustEngine, peerEntityRole); - if (metadataProvider instanceof IRefreshableMetadataProvider) - this.metadataProvider = (IRefreshableMetadataProvider) metadataProvider; - - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.validation.AbstractRequestSignedSecurityPolicyRule#refreshMetadataProvider(java.lang.String) - */ - @Override - protected boolean refreshMetadataProvider(String entityID) { - if (metadataProvider != null) - return metadataProvider.refreshMetadataProvider(entityID); - - return false; - - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.validation.AbstractRequestSignedSecurityPolicyRule#getSignedSAMLObject(org.opensaml.xml.XMLObject) - */ - @Override - protected SignableSAMLObject getSignedSAMLObject(XMLObject inboundData) { - if (inboundData instanceof SignableSAMLObject) - return (SignableSAMLObject) inboundData; - - else - return null; - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PvpAuthRequestSignedRole.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PvpAuthRequestSignedRole.java new file mode 100644 index 00000000..4eb711f9 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PvpAuthRequestSignedRole.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.verification; + +import java.util.List; +import org.opensaml.common.binding.SAMLMessageContext; +import org.opensaml.saml2.binding.security.SAML2AuthnRequestsSignedRule; +import org.opensaml.ws.transport.http.HTTPInTransport; +import org.opensaml.xml.util.DatatypeHelper; + +public class PvpAuthRequestSignedRole extends SAML2AuthnRequestsSignedRule { + + @Override + protected boolean isMessageSigned(final SAMLMessageContext messageContext) { + // This handles HTTP-Redirect and HTTP-POST-SimpleSign bindings. + final HTTPInTransport inTransport = + (HTTPInTransport) messageContext.getInboundMessageTransport(); + + // Check signature parameter exists only once and is not empty + final List<String> sigParam = inTransport.getParameterValues("Signature"); + final boolean isValidSigned = sigParam.size() == 1 && !DatatypeHelper.isEmpty(sigParam.get(0)); + + // Check signature-algorithm parameter exists only once and is not empty + final List<String> sigAlgParam = inTransport.getParameterValues("SigAlg"); + final boolean isValidSigAlgExists = + sigAlgParam.size() == 1 && !DatatypeHelper.isEmpty(sigAlgParam.get(0)); + + // Check signature-content parameter exists only once and is not empty + final List<String> samlReqParam = inTransport.getParameterValues("SAMLRequest"); + final List<String> samlRespParam = inTransport.getParameterValues("SAMLResponse"); + final boolean isValidContent = + ((samlReqParam.size() == 1 && !DatatypeHelper.isEmpty(samlReqParam.get(0))) + || (samlRespParam.size() == 1 && !DatatypeHelper.isEmpty(samlRespParam.get(0)))) + && !(samlReqParam.size() == 1 && samlRespParam.size() == 1); + + return isValidSigned && isValidSigAlgExists && isValidContent; + + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PvpSignedRequestPolicyRule.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PvpSignedRequestPolicyRule.java new file mode 100644 index 00000000..0d108596 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/PvpSignedRequestPolicyRule.java @@ -0,0 +1,82 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.verification; + +import javax.xml.namespace.QName; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; +import org.opensaml.common.SignableSAMLObject; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.signature.SignatureTrustEngine; + +public class PvpSignedRequestPolicyRule extends AbstractRequestSignedSecurityPolicyRule { + + private IRefreshableMetadataProvider metadataProvider = null; + + /** + * EAAF specific signature rule for OpenSAML2 redirect-binding. + * + * @param metadataProvider SAML2 metadata provider + * @param trustEngine SAML2 TrustEngine + * @param peerEntityRole Role of the Entity + */ + public PvpSignedRequestPolicyRule(final MetadataProvider metadataProvider, + final SignatureTrustEngine trustEngine, final QName peerEntityRole) { + super(trustEngine, peerEntityRole); + if (metadataProvider instanceof IRefreshableMetadataProvider) { + this.metadataProvider = (IRefreshableMetadataProvider) metadataProvider; + } + + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.validation.AbstractRequestSignedSecurityPolicyRule# + * refreshMetadataProvider(java.lang.String) + */ + @Override + protected boolean refreshMetadataProvider(final String entityID) { + if (metadataProvider != null) { + return metadataProvider.refreshMetadataProvider(entityID); + } + + return false; + + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.validation.AbstractRequestSignedSecurityPolicyRule# + * getSignedSAMLObject(org.opensaml.xml.XMLObject) + */ + @Override + protected SignableSAMLObject getSignedSamlObject(final XMLObject inboundData) { + if (inboundData instanceof SignableSAMLObject) { + return (SignableSAMLObject) inboundData; + } else { + return null; + } + } + +} 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 deleted file mode 100644 index 078e4ac0..00000000 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SAMLVerificationEngine.java +++ /dev/null @@ -1,207 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.impl.verification; - -import javax.xml.namespace.QName; -import javax.xml.transform.dom.DOMSource; -import javax.xml.validation.Schema; -import javax.xml.validation.Validator; - -import org.apache.commons.lang3.StringUtils; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.common.xml.SAMLSchemaBuilder; -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.security.MetadataCriteria; -import org.opensaml.security.SAMLSignatureProfileValidator; -import org.opensaml.xml.security.CriteriaSet; -import org.opensaml.xml.security.credential.UsageType; -import org.opensaml.xml.security.criteria.EntityIDCriteria; -import org.opensaml.xml.security.criteria.UsageCriteria; -import org.opensaml.xml.signature.SignatureTrustEngine; -import org.opensaml.xml.validation.ValidationException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; -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; - -@Service("SAMLVerificationEngine") -public class SAMLVerificationEngine { - private static final Logger log = LoggerFactory.getLogger(SAMLVerificationEngine.class); - - - @Autowired(required=true) IPVPMetadataProvider metadataProvider; - - public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { - try { - if (msg instanceof PVPSProfileRequest && - ((PVPSProfileRequest)msg).getSamlRequest() instanceof RequestAbstractType) - verifyRequest(((RequestAbstractType)((PVPSProfileRequest)msg).getSamlRequest()), sigTrustEngine); - - else - verifyIDPResponse(((PVPSProfileResponse)msg).getResponse(), sigTrustEngine); - - } catch (InvalidProtocolRequestException e) { - if (StringUtils.isEmpty(msg.getEntityID())) { - throw e; - - } - 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); - - else - verifyIDPResponse(((PVPSProfileResponse)msg).getResponse(), sigTrustEngine); - - } - log.trace("Second PVP2X message validation finished"); - } - } - - public void verifySLOResponse(StatusResponseType samlObj, SignatureTrustEngine sigTrustEngine ) throws InvalidProtocolRequestException { - verifyResponse(samlObj, sigTrustEngine, SPSSODescriptor.DEFAULT_ELEMENT_NAME); - - } - - public void verifyIDPResponse(StatusResponseType samlObj, SignatureTrustEngine sigTrustEngine) throws InvalidProtocolRequestException{ - verifyResponse(samlObj, sigTrustEngine, IDPSSODescriptor.DEFAULT_ELEMENT_NAME); - - } - - private void verifyResponse(StatusResponseType samlObj, SignatureTrustEngine sigTrustEngine, QName defaultElementName) throws InvalidProtocolRequestException{ - SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); - try { - profileValidator.validate(samlObj.getSignature()); - performSchemaValidation(samlObj.getDOM()); - - } catch (ValidationException e) { - log.warn("Signature is not conform to SAML signature profile", e); - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - - } catch (SchemaValidationException e) { - throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); - - } - - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add( new EntityIDCriteria(samlObj.getIssuer().getValue()) ); - criteriaSet.add( new MetadataCriteria(defaultElementName, SAMLConstants.SAML20P_NS) ); - criteriaSet.add( new UsageCriteria(UsageType.SIGNING) ); - - try { - if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) { - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - } - } catch (org.opensaml.xml.security.SecurityException e) { - log.warn("PVP2x message signature validation FAILED.", e); - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - } - } - - private void verifyRequest(RequestAbstractType samlObj, SignatureTrustEngine sigTrustEngine ) throws InvalidProtocolRequestException { - SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); - try { - profileValidator.validate(samlObj.getSignature()); - performSchemaValidation(samlObj.getDOM()); - - } catch (ValidationException e) { - log.warn("Signature is not conform to SAML signature profile", e); - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - - } catch (SchemaValidationException e) { - throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); - - } - - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add( new EntityIDCriteria(samlObj.getIssuer().getValue()) ); - criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); - criteriaSet.add( new UsageCriteria(UsageType.SIGNING) ); - - try { - if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) { - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - } - } catch (org.opensaml.xml.security.SecurityException e) { - log.warn("PVP2x message signature validation FAILED.", e); - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - } - } - - protected void performSchemaValidation(Element source) throws SchemaValidationException { - - String err = null; - try { - Schema test = SAMLSchemaBuilder.getSAML11Schema(); - Validator val = test.newValidator(); - val.validate(new DOMSource(source)); - log.debug("Schema validation check done OK"); - return; - - } catch (SAXException e) { - err = e.getMessage(); - if (log.isDebugEnabled() || log.isTraceEnabled()) - log.warn("Schema validation FAILED with exception:", e); - else - log.warn("Schema validation FAILED with message: "+ e.getMessage()); - - } catch (Exception e) { - err = e.getMessage(); - if (log.isDebugEnabled() || log.isTraceEnabled()) - log.warn("Schema validation FAILED with exception:", e); - else - log.warn("Schema validation FAILED with message: "+ e.getMessage()); - - } - - throw new SchemaValidationException("pvp2.22", new Object[]{err}); - - } - -} 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 new file mode 100644 index 00000000..64eb5247 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java @@ -0,0 +1,218 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.impl.verification; + +import javax.xml.namespace.QName; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.Validator; +import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; +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 org.apache.commons.lang3.StringUtils; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.common.xml.SAMLSchemaBuilder; +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.security.MetadataCriteria; +import org.opensaml.security.SAMLSignatureProfileValidator; +import org.opensaml.xml.security.CriteriaSet; +import org.opensaml.xml.security.credential.UsageType; +import org.opensaml.xml.security.criteria.EntityIDCriteria; +import org.opensaml.xml.security.criteria.UsageCriteria; +import org.opensaml.xml.signature.SignatureTrustEngine; +import org.opensaml.xml.validation.ValidationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +@Service("SAMLVerificationEngine") +public class SamlVerificationEngine { + private static final Logger log = LoggerFactory.getLogger(SamlVerificationEngine.class); + + + @Autowired(required = true) + IPvpMetadataProvider metadataProvider; + + /** + * Verify signature of a signed SAML2 object. + * + * @param msg SAML2 message + * @param sigTrustEngine TrustEngine + * @throws org.opensaml.xml.security.SecurityException In case of invalid signature + * @throws Exception In case of a general error + */ + public void verify(final InboundMessage msg, final SignatureTrustEngine sigTrustEngine) + throws org.opensaml.xml.security.SecurityException, Exception { + try { + if (msg instanceof PvpSProfileRequest + && ((PvpSProfileRequest) msg).getSamlRequest() instanceof RequestAbstractType) { + verifyRequest(((RequestAbstractType) ((PvpSProfileRequest) msg).getSamlRequest()), + sigTrustEngine); + } else { + verifyIdpResponse(((PvpSProfileResponse) msg).getResponse(), sigTrustEngine); + } + + } catch (final InvalidProtocolRequestException e) { + if (StringUtils.isEmpty(msg.getEntityID())) { + throw e; + + } + 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); + } else { + verifyIdpResponse(((PvpSProfileResponse) msg).getResponse(), sigTrustEngine); + } + + } + log.trace("Second PVP2X message validation finished"); + } + } + + public void verifySloResponse(final StatusResponseType samlObj, + final SignatureTrustEngine sigTrustEngine) throws InvalidProtocolRequestException { + verifyResponse(samlObj, sigTrustEngine, SPSSODescriptor.DEFAULT_ELEMENT_NAME); + + } + + public void verifyIdpResponse(final StatusResponseType samlObj, + final SignatureTrustEngine sigTrustEngine) throws InvalidProtocolRequestException { + verifyResponse(samlObj, sigTrustEngine, IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + + } + + private void verifyResponse(final StatusResponseType samlObj, + final SignatureTrustEngine sigTrustEngine, final QName defaultElementName) + throws InvalidProtocolRequestException { + final SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); + try { + profileValidator.validate(samlObj.getSignature()); + performSchemaValidation(samlObj.getDOM()); + + } catch (final ValidationException e) { + log.warn("Signature is not conform to SAML signature profile", e); + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + + } catch (final SchemaValidationException e) { + throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); + + } + + final CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new EntityIDCriteria(samlObj.getIssuer().getValue())); + criteriaSet.add(new MetadataCriteria(defaultElementName, SAMLConstants.SAML20P_NS)); + criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); + + try { + if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) { + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + } + } catch (final org.opensaml.xml.security.SecurityException e) { + log.warn("PVP2x message signature validation FAILED.", e); + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + } + } + + private void verifyRequest(final RequestAbstractType samlObj, + final SignatureTrustEngine sigTrustEngine) throws InvalidProtocolRequestException { + final SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); + try { + profileValidator.validate(samlObj.getSignature()); + performSchemaValidation(samlObj.getDOM()); + + } catch (final ValidationException e) { + log.warn("Signature is not conform to SAML signature profile", e); + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + + } catch (final SchemaValidationException e) { + throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); + + } + + final CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new EntityIDCriteria(samlObj.getIssuer().getValue())); + criteriaSet + .add(new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS)); + criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); + + try { + if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) { + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + } + } catch (final org.opensaml.xml.security.SecurityException e) { + log.warn("PVP2x message signature validation FAILED.", e); + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + } + } + + protected void performSchemaValidation(final Element source) throws SchemaValidationException { + + String err = null; + try { + final Schema test = SAMLSchemaBuilder.getSAML11Schema(); + final Validator val = test.newValidator(); + val.validate(new DOMSource(source)); + log.debug("Schema validation check done OK"); + return; + + } catch (final SAXException e) { + err = e.getMessage(); + if (log.isDebugEnabled() || log.isTraceEnabled()) { + log.warn("Schema validation FAILED with exception:", e); + } else { + log.warn("Schema validation FAILED with message: " + e.getMessage()); + } + + } catch (final Exception e) { + err = e.getMessage(); + if (log.isDebugEnabled() || log.isTraceEnabled()) { + log.warn("Schema validation FAILED with exception:", e); + } else { + log.warn("Schema validation FAILED with message: " + e.getMessage()); + } + + } + + throw new SchemaValidationException("pvp2.22", new Object[] {err}); + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider index 9c60d724..8bc7508c 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider @@ -1 +1 @@ -at.gv.egiz.eaaf.modules.pvp2.PVP2SProfileCoreSpringResourceProvider
\ No newline at end of file +at.gv.egiz.eaaf.modules.pvp2.Pvp2SProfileCoreSpringResourceProvider
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/eaaf_pvp.beans.xml b/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/eaaf_pvp.beans.xml index 2cbcce20..ee4d3864 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/eaaf_pvp.beans.xml +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/eaaf_pvp.beans.xml @@ -1,30 +1,25 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- - --> - -<!-- - --> <beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xmlns:tx="http://www.springframework.org/schema/tx" - xmlns:aop="http://www.springframework.org/schema/aop" - xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd - http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> - - <bean id="PVPMetadataBuilder" - class="at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPMetadataBuilder" /> - - <bean id="PVPPOSTBinding" - class="at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding" /> - - <bean id="PVPRedirectBinding" - class="at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding" /> - - <bean id="PVPSOAPBinding" - class="at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding" /> - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> + + <bean id="PVPMetadataBuilder" + class="at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder" /> + + <bean id="PVPPOSTBinding" + class="at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding" /> + + <bean id="PVPRedirectBinding" + class="at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding" /> + + <bean id="PVPSOAPBinding" + class="at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding" /> + </beans>
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java deleted file mode 100644 index d50c5ee4..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import at.gv.egiz.components.spring.api.SpringResourceProvider; - -public class PVP2SProfileIDPSpringResourceProvider implements SpringResourceProvider { - - @Override - public String getName() { - return "EAAF PVP2 S-Profile IDP SpringResourceProvider"; - } - - @Override - public String[] getPackagesToScan() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource[] getResourcesToLoad() { - ClassPathResource sl20AuthConfig = new ClassPathResource("/eaaf_pvp_idp.beans.xml", PVP2SProfileIDPSpringResourceProvider.class); - - return new Resource[] {sl20AuthConfig}; - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java new file mode 100644 index 00000000..9414dc33 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.idp; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +public class Pvp2SProfileIdpSpringResourceProvider implements SpringResourceProvider { + + @Override + public String getName() { + return "EAAF PVP2 S-Profile IDP SpringResourceProvider"; + } + + @Override + public String[] getPackagesToScan() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource[] getResourcesToLoad() { + final ClassPathResource sl20AuthConfig = new ClassPathResource("/eaaf_pvp_idp.beans.xml", + Pvp2SProfileIdpSpringResourceProvider.class); + + return new Resource[] {sl20AuthConfig}; + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java index 90662f48..131be543 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java @@ -1,45 +1,39 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.api.builder; import at.gv.egiz.eaaf.core.api.idp.IAuthData; -import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; +import at.gv.egiz.eaaf.core.api.idp.IspConfiguration; import at.gv.egiz.eaaf.core.impl.data.Pair; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; public interface ISubjectNameIdGenerator { - /** - * Generates a SAML2 subjectNameId from authentication data - * - * @param authData Authentication data for the current pending request - * @param spConfig Service provider configuration - * @return Pair of subjectNameId and NameIdFormat - * @throws PVP2Exception - */ - public Pair<String, String> generateSubjectNameId(IAuthData authData, ISPConfiguration spConfig) throws PVP2Exception; + /** + * Generates a SAML2 subjectNameId from authentication data. + * + * @param authData Authentication data for the current pending request + * @param spConfig Service provider configuration + * @return Pair of subjectNameId and NameIdFormat + * @throws Pvp2Exception In case of an error + */ + public Pair<String, String> generateSubjectNameId(IAuthData authData, IspConfiguration spConfig) + throws Pvp2Exception; } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java index 42424726..6d868558 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java @@ -1,54 +1,47 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.saml2.core.StatusCode; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +public class InvalidAssertionConsumerServiceException extends Pvp2Exception { + + private static final long serialVersionUID = 7861790149343943091L; + + public InvalidAssertionConsumerServiceException(final int idx) { + super("pvp2.28", new Object[] {idx}); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } -public class InvalidAssertionConsumerServiceException extends PVP2Exception { + /** + * Invalid assertion consumer-service URL. + * + * @param wrongUrl invalid URL + */ + public InvalidAssertionConsumerServiceException(final String wrongUrl) { + super("pvp2.23", new Object[] {wrongUrl}); + this.statusCodeValue = StatusCode.REQUESTER_URI; - public InvalidAssertionConsumerServiceException(int idx) { - super("pvp2.28", new Object[]{idx}); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } + } - /** - * - */ - public InvalidAssertionConsumerServiceException(String wrongURL) { - super("pvp2.23", new Object[]{wrongURL}); - this.statusCodeValue = StatusCode.REQUESTER_URI; - - } - /** - * - */ - private static final long serialVersionUID = 7861790149343943091L; } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java index 55c94df1..0d75616a 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java @@ -1,42 +1,34 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.saml2.core.StatusCode; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; - -public class InvalidAssertionEncryptionException extends PVP2Exception { +public class InvalidAssertionEncryptionException extends Pvp2Exception { - private static final long serialVersionUID = 6513388841485355549L; + private static final long serialVersionUID = 6513388841485355549L; - public InvalidAssertionEncryptionException() { - super("pvp2.16", new Object[]{}); - this.statusCodeValue = StatusCode.RESPONDER_URI; - } + public InvalidAssertionEncryptionException() { + super("pvp2.16", new Object[] {}); + this.statusCodeValue = StatusCode.RESPONDER_URI; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java index 6109c78d..ecceea12 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java @@ -1,45 +1,34 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.saml2.core.StatusCode; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; - -public class RequestDeniedException extends PVP2Exception { +public class RequestDeniedException extends Pvp2Exception { - public RequestDeniedException() { - super("pvp2.14", null); - this.statusCodeValue = StatusCode.REQUEST_DENIED_URI; - } + private static final long serialVersionUID = 4415896615794730553L; - /** - * - */ - private static final long serialVersionUID = 4415896615794730553L; + public RequestDeniedException() { + super("pvp2.14", null); + this.statusCodeValue = StatusCode.REQUEST_DENIED_URI; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java index 7f565c00..331e11cd 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java @@ -1,50 +1,39 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.saml2.core.StatusCode; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +public class ResponderErrorException extends Pvp2Exception { -public class ResponderErrorException extends PVP2Exception { + private static final long serialVersionUID = -425416760138285446L; - /** - * - */ - private static final long serialVersionUID = -425416760138285446L; + public ResponderErrorException(final String messageId, final Object[] parameters, + final Throwable wrapped) { + super(messageId, parameters, wrapped); + this.statusCodeValue = StatusCode.RESPONDER_URI; + } - public ResponderErrorException(String messageId, Object[] parameters, - Throwable wrapped) { - super(messageId, parameters, wrapped); - this.statusCodeValue = StatusCode.RESPONDER_URI; - } - - public ResponderErrorException(String messageId, Object[] parameters) { - super(messageId, parameters); - this.statusCodeValue = StatusCode.RESPONDER_URI; - } + public ResponderErrorException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + this.statusCodeValue = StatusCode.RESPONDER_URI; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java deleted file mode 100644 index a0fad363..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp.exception; - -import org.opensaml.saml2.core.StatusCode; - -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; - -public class SAMLRequestNotSignedException extends PVP2Exception { - - public SAMLRequestNotSignedException() { - super("pvp2.07", null); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - - public SAMLRequestNotSignedException(Throwable e) { - super("pvp2.07", null, e); - this.statusCodeValue = StatusCode.REQUESTER_URI; - } - - /** - * - */ - private static final long serialVersionUID = 1L; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java deleted file mode 100644 index e59ebe0a..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp.exception; - -import org.opensaml.saml2.core.StatusCode; - -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; - - -public class SAMLRequestNotSupported extends PVP2Exception { - - public SAMLRequestNotSupported() { - super("pvp2.09", null); - this.statusCodeValue = StatusCode.REQUEST_UNSUPPORTED_URI; - } - - /** - * - */ - private static final long serialVersionUID = 1244883178458802767L; - -} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java new file mode 100644 index 00000000..4650506d --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.idp.exception; + +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import org.opensaml.saml2.core.StatusCode; + +public class SamlRequestNotSignedException extends Pvp2Exception { + + private static final long serialVersionUID = 1L; + + public SamlRequestNotSignedException() { + super("pvp2.07", null); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } + + public SamlRequestNotSignedException(final Throwable e) { + super("pvp2.07", null, e); + this.statusCodeValue = StatusCode.REQUESTER_URI; + } + + + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java new file mode 100644 index 00000000..58a493b9 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.idp.exception; + +import org.opensaml.saml2.core.StatusCode; + +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; + + +public class SamlRequestNotSupported extends Pvp2Exception { + + private static final long serialVersionUID = 1244883178458802767L; + + public SamlRequestNotSupported() { + super("pvp2.09", null); + this.statusCodeValue = StatusCode.REQUEST_UNSUPPORTED_URI; + } + + + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java index 0dfda55f..41252b78 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java @@ -1,43 +1,33 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; import org.opensaml.saml2.core.StatusCode; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +public class UnprovideableAttributeException extends Pvp2Exception { -public class UnprovideableAttributeException extends PVP2Exception { - /** - * - */ - private static final long serialVersionUID = 3972197758163647157L; + private static final long serialVersionUID = 3972197758163647157L; - public UnprovideableAttributeException(String attributeName) { - super("pvp2.10", new Object[] {attributeName}); - this.statusCodeValue = StatusCode.UNKNOWN_ATTR_PROFILE_URI; - } + public UnprovideableAttributeException(final String attributeName) { + super("pvp2.10", new Object[] {attributeName}); + this.statusCodeValue = StatusCode.UNKNOWN_ATTR_PROFILE_URI; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPVP2XProtocol.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPVP2XProtocol.java deleted file mode 100644 index 3298559a..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPVP2XProtocol.java +++ /dev/null @@ -1,541 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp.impl; - -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.core.Issuer; -import org.opensaml.saml2.core.NameID; -import org.opensaml.saml2.core.Response; -import org.opensaml.saml2.core.Status; -import org.opensaml.saml2.core.StatusCode; -import org.opensaml.saml2.core.StatusMessage; -import org.opensaml.saml2.metadata.AssertionConsumerService; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.opensaml.ws.security.SecurityPolicyException; -import org.opensaml.xml.security.x509.X509Credential; -import org.opensaml.xml.signature.SignableXMLObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import at.gv.egiz.components.eventlog.api.EventConstants; -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.core.api.idp.IModulInfo; -import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; -import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException; -import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException; -import at.gv.egiz.eaaf.core.exceptions.SLOException; -import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController; -import at.gv.egiz.eaaf.modules.pvp2.PVPEventConstants; -import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestValidator; -import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidPVPRequestException; -import at.gv.egiz.eaaf.modules.pvp2.exception.NameIDFormatNotSupportedException; -import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionConsumerServiceException; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding; -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.utils.AbstractCredentialProvider; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; -import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EAAFURICompare; -import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; -import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SAMLVerificationEngine; - -public abstract class AbstractPVP2XProtocol extends AbstractController implements IModulInfo { - private static final Logger log = LoggerFactory.getLogger(AbstractPVP2XProtocol.class); - - @Autowired(required=true) protected IPVP2BasicConfiguration pvpBasicConfiguration; - @Autowired(required=true) protected IPVPMetadataProvider metadataProvider; - @Autowired(required=true) protected SAMLVerificationEngine samlVerificationEngine; - @Autowired(required=true) protected IAuthnRequestValidator authRequestValidator; - - private AbstractCredentialProvider pvpIDPCredentials; - - - - /** - * Sets a specific credential provider for PVP S-Profile IDP component. - * @param pvpIDPCredentials credential provider - */ - public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) { - this.pvpIDPCredentials = pvpIDPCredentials; - - } - - public boolean generateErrorMessage(Throwable e, - HttpServletRequest request, HttpServletResponse response, - IRequest protocolRequest) throws Throwable { - - if(protocolRequest == null) { - throw e; - } - - if(!(protocolRequest instanceof PVPSProfilePendingRequest) ) { - throw e; - } - PVPSProfilePendingRequest pvpRequest = (PVPSProfilePendingRequest)protocolRequest; - - Response samlResponse = - SAML2Utils.createSAMLObject(Response.class); - Status status = SAML2Utils.createSAMLObject(Status.class); - StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class); - StatusMessage statusMessage = SAML2Utils.createSAMLObject(StatusMessage.class); - - String moaError = null; - - if(e instanceof NoPassivAuthenticationException) { - statusCode.setValue(StatusCode.NO_PASSIVE_URI); - statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())); - - } else if (e instanceof NameIDFormatNotSupportedException) { - statusCode.setValue(StatusCode.INVALID_NAMEID_POLICY_URI); - statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())); - - } else if (e instanceof SLOException) { - //SLOExecpetions only occurs if session information is lost - return false; - - } else if(e instanceof PVP2Exception) { - PVP2Exception ex = (PVP2Exception) e; - statusCode.setValue(ex.getStatusCodeValue()); - String statusMessageValue = ex.getStatusMessageValue(); - if(statusMessageValue != null) { - statusMessage.setMessage(StringEscapeUtils.escapeXml(statusMessageValue)); - } - moaError = statusMessager.mapInternalErrorToExternalError(ex.getErrorId()); - - } else { - statusCode.setValue(StatusCode.RESPONDER_URI); - statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())); - moaError = statusMessager.getResponseErrorCode(e); - } - - - if (StringUtils.isNotEmpty(moaError)) { - StatusCode moaStatusCode = SAML2Utils.createSAMLObject(StatusCode.class); - moaStatusCode.setValue(moaError); - statusCode.setStatusCode(moaStatusCode); - } - - status.setStatusCode(statusCode); - if(statusMessage.getMessage() != null) { - status.setStatusMessage(statusMessage); - } - samlResponse.setStatus(status); - String remoteSessionID = SAML2Utils.getSecureIdentifier(); - samlResponse.setID(remoteSessionID); - - samlResponse.setIssueInstant(new DateTime()); - Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); - nissuer.setValue(pvpBasicConfiguration.getIDPEntityId(pvpRequest.getAuthURL())); - nissuer.setFormat(NameID.ENTITY); - samlResponse.setIssuer(nissuer); - - IEncoder encoder = null; - - if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { - encoder = applicationContext.getBean("PVPRedirectBinding", RedirectBinding.class); - - } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { - encoder = applicationContext.getBean("PVPPOSTBinding", PostBinding.class); - - } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) { - encoder = applicationContext.getBean("PVPSOAPBinding", SoapBinding.class); - } - - if(encoder == null) { - // default to redirect binding - encoder = new RedirectBinding(); - } - - String relayState = null; - if (pvpRequest.getRequest() != null) - relayState = pvpRequest.getRequest().getRelayState(); - - X509Credential signCred = pvpIDPCredentials.getIDPAssertionSigningCredential(); - - encoder.encodeRespone(request, response, samlResponse, pvpRequest.getConsumerURL(), - relayState, signCred, protocolRequest); - return true; - } - - public boolean validate(HttpServletRequest request, - HttpServletResponse response, IRequest pending) { - - return true; - } - - protected void pvpMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { - //create pendingRequest object - PVPSProfilePendingRequest pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class); - pendingReq.initialize(req, authConfig); - pendingReq.setModule(getName()); - - revisionsLogger.logEvent( - pendingReq.getUniqueSessionIdentifier(), - pendingReq.getUniqueTransactionIdentifier(), - EventConstants.TRANSACTION_IP, - req.getRemoteAddr()); - - MetadataAction metadataAction = applicationContext.getBean(MetadataAction.class); - metadataAction.processRequest(pendingReq, - req, resp, null); - - } - - protected void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { - PVPSProfilePendingRequest pendingReq = null; - - try { - //create pendingRequest object - pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class); - pendingReq.initialize(req, authConfig); - pendingReq.setModule(getName()); - - revisionsLogger.logEvent(EventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier()); - revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier()); - revisionsLogger.logEvent( - pendingReq.getUniqueSessionIdentifier(), - pendingReq.getUniqueTransactionIdentifier(), - EventConstants.TRANSACTION_IP, - req.getRemoteAddr()); - - //get POST-Binding decoder implementation - InboundMessage msg = (InboundMessage) new PostBinding().decode( - req, resp, metadataProvider, false, - new EAAFURICompare(pvpBasicConfiguration.getIDPSSOPostService(pendingReq.getAuthURL()))); - pendingReq.setRequest(msg); - - //preProcess Message - preProcess(req, resp, pendingReq); - - } catch (SecurityPolicyException e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.warn("Receive INVALID protocol request: " + samlRequest, e); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - - } catch (SecurityException e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.warn("Receive INVALID protocol request: " + samlRequest, e); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); - - } catch (EAAFException e) { - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw e; - - } catch (Throwable e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.warn("Receive INVALID protocol request: " + samlRequest, e); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw new EAAFException("pvp2.24", new Object[] {e.getMessage()}, e); - } - } - - protected void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { - PVPSProfilePendingRequest pendingReq = null; - try { - //create pendingRequest object - pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class); - pendingReq.initialize(req, authConfig); - pendingReq.setModule(getName()); - - revisionsLogger.logEvent(EventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier()); - revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier()); - revisionsLogger.logEvent( - pendingReq.getUniqueSessionIdentifier(), - pendingReq.getUniqueTransactionIdentifier(), - EventConstants.TRANSACTION_IP, - req.getRemoteAddr()); - - //get POST-Binding decoder implementation - InboundMessage msg = (InboundMessage) new RedirectBinding().decode( - req, resp, metadataProvider, false, - new EAAFURICompare(pvpBasicConfiguration.getIDPSSORedirectService(pendingReq.getAuthURL()))); - pendingReq.setRequest(msg); - - //preProcess Message - preProcess(req, resp, pendingReq); - - } catch (SecurityPolicyException e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.warn("Receive INVALID protocol request: " + samlRequest, e); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); - - } catch (SecurityException e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.warn("Receive INVALID protocol request: " + samlRequest, e); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); - - } catch (EAAFException e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.info("Receive INVALID protocol request: " + samlRequest); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw e; - - } catch (Throwable e) { - String samlRequest = req.getParameter("SAMLRequest"); - log.warn("Receive INVALID protocol request: " + samlRequest, e); - - //write revision log entries - if (pendingReq != null) - revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - - throw new EAAFException("pvp2.24", new Object[] {e.getMessage()}, e); - } - } - - - - /** - * - * - * @param request - * @param response - * @param msg - * @return true if preprocess can handle this request type, otherwise false - * @throws Throwable - */ - abstract protected boolean childPreProcess(HttpServletRequest request, - HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable; - - protected void preProcess(HttpServletRequest request, - HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable { - - InboundMessage msg = pendingReq.getRequest(); - - if (StringUtils.isEmpty(msg.getEntityID())) { - throw new InvalidProtocolRequestException("pvp2.20", new Object[] {}); - - } - - if(!msg.isVerified()) { - samlVerificationEngine.verify(msg, - TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); - msg.setVerified(true); - - } - - revisionsLogger.logEvent(pendingReq, IRevisionLogger.AUTHPROTOCOL_TYPE, getAuthProtocolIdentifier()); - - if (msg instanceof PVPSProfileRequest && - ((PVPSProfileRequest)msg).getSamlRequest() instanceof AuthnRequest) - preProcessAuthRequest(request, response, pendingReq); - - else if (childPreProcess(request, response, pendingReq)) - log.debug("Find protocol handler in child implementation"); - - else { - log.error("Receive unsupported PVP21 message of type: " + ((PVPSProfileRequest)msg).getSamlRequest().getClass().getName()); - throw new InvalidPVPRequestException("pvp2.09", - new Object[] {((PVPSProfileRequest)msg).getSamlRequest().getClass().getName()}); - } - - - - //switch to session authentication - protAuthService.performAuthentication(request, response, pendingReq); - } - - - /** - * PreProcess Authn request - * @param request - * @param response - * @param pendingReq - * @throws Throwable - */ - private void preProcessAuthRequest(HttpServletRequest request, - HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable { - - PVPSProfileRequest moaRequest = ((PVPSProfileRequest)pendingReq.getRequest()); - SignableXMLObject samlReq = moaRequest.getSamlRequest(); - - if(!(samlReq instanceof AuthnRequest)) { - throw new InvalidPVPRequestException("Unsupported request", new Object[] {}); - } - - EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider); - if(metadata == null) { - throw new NoMetadataInformationException(); - } - SPSSODescriptor spSSODescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); - - AuthnRequest authnRequest = (AuthnRequest)samlReq; - - if (authnRequest.getIssueInstant() == null) { - log.warn("Unsupported request: No IssueInstant Attribute found."); - throw new AuthnRequestValidatorException("pvp2.22", - new Object[] {"Unsupported request: No IssueInstant Attribute found"}, - pendingReq); - - } - - if (authnRequest.getIssueInstant().minusMinutes(EAAFConstants.ALLOWED_TIME_JITTER).isAfterNow()) { - log.warn("Unsupported request: No IssueInstant DateTime is not valid anymore."); - throw new AuthnRequestValidatorException("pvp2.22", - new Object[] {"Unsupported request: No IssueInstant DateTime is not valid anymore."}, - pendingReq); - - } - - //parse AssertionConsumerService - AssertionConsumerService consumerService = null; - if (StringUtils.isNotEmpty(authnRequest.getAssertionConsumerServiceURL()) && - StringUtils.isNotEmpty(authnRequest.getProtocolBinding())) { - //use AssertionConsumerServiceURL from request - - //check requested AssertionConsumingService URL against metadata - List<AssertionConsumerService> metadataAssertionServiceList = spSSODescriptor.getAssertionConsumerServices(); - for (AssertionConsumerService service : metadataAssertionServiceList) { - if (authnRequest.getProtocolBinding().equals(service.getBinding()) - && authnRequest.getAssertionConsumerServiceURL().equals(service.getLocation())) { - consumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class); - consumerService.setBinding(authnRequest.getProtocolBinding()); - consumerService.setLocation(authnRequest.getAssertionConsumerServiceURL()); - log.debug("Requested AssertionConsumerServiceURL is valid."); - } - } - - if (consumerService == null) { - throw new InvalidAssertionConsumerServiceException(authnRequest.getAssertionConsumerServiceURL()); - - } - - - } else { - //use AssertionConsumerServiceIndex and select consumerService from metadata - Integer aIdx = authnRequest.getAssertionConsumerServiceIndex(); - int assertionidx = 0; - - if(aIdx != null) { - assertionidx = aIdx.intValue(); - - } else { - assertionidx = SAML2Utils.getDefaultAssertionConsumerServiceIndex(spSSODescriptor); - - } - consumerService = spSSODescriptor.getAssertionConsumerServices().get(assertionidx); - - if (consumerService == null) { - throw new InvalidAssertionConsumerServiceException(aIdx); - - } - } - - - //validate AuthnRequest - AuthnRequest authReq = (AuthnRequest) samlReq; - String oaURL = moaRequest.getEntityMetadata(metadataProvider).getEntityID(); - log.info("Dispatch PVP2 AuthnRequest: OAURL=" + oaURL + " Binding=" + consumerService.getBinding()); - - pendingReq.setSPEntityId(StringEscapeUtils.escapeHtml(oaURL)); - pendingReq.setOnlineApplicationConfiguration(authConfig.getServiceProviderConfiguration(pendingReq.getSPEntityId())); - pendingReq.setBinding(consumerService.getBinding()); - pendingReq.setRequest(moaRequest); - pendingReq.setConsumerURL(consumerService.getLocation()); - - //parse AuthRequest - pendingReq.setPassiv(authReq.isPassive()); - pendingReq.setForce(authReq.isForceAuthn()); - - //AuthnRequest needs authentication - pendingReq.setNeedAuthentication(true); - - //set protocol action, which should be executed after authentication - pendingReq.setAction(AuthenticationAction.class.getName()); - - log.trace("Starting extended AuthnRequest validation and processing ... "); - authRequestValidator.validate(request, pendingReq, authReq, spSSODescriptor); - log.debug("Extended AuthnRequest validation and processing finished"); - - //write revisionslog entry - revisionsLogger.logEvent(pendingReq, PVPEventConstants.AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST, authReq.getID()); - - } - - @PostConstruct - private void verifyInitialization() { - if (pvpIDPCredentials == null) { - log.error("No SAML2 credentialProvider injected!"); - throw new RuntimeException("No SAML2 credentialProvider injected!"); - - } - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java new file mode 100644 index 00000000..3fac7894 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java @@ -0,0 +1,561 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.idp.impl; + +import java.util.List; +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import at.gv.egiz.components.eventlog.api.EventConstants; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.core.api.idp.IModulInfo; +import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; +import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException; +import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.SloException; +import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController; +import at.gv.egiz.eaaf.modules.pvp2.PvpEventConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvo2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestValidator; +import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidPvpRequestException; +import at.gv.egiz.eaaf.modules.pvp2.exception.NameIdFormatNotSupportedException; +import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionConsumerServiceException; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding; +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.utils.AbstractCredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.AuthnRequest; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.core.Response; +import org.opensaml.saml2.core.Status; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.core.StatusMessage; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.ws.security.SecurityPolicyException; +import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.signature.SignableXMLObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class AbstractPvp2XProtocol extends AbstractController implements IModulInfo { + private static final Logger log = LoggerFactory.getLogger(AbstractPvp2XProtocol.class); + + @Autowired(required = true) + protected IPvo2BasicConfiguration pvpBasicConfiguration; + @Autowired(required = true) + protected IPvpMetadataProvider metadataProvider; + @Autowired(required = true) + protected SamlVerificationEngine samlVerificationEngine; + @Autowired(required = true) + protected IAuthnRequestValidator authRequestValidator; + + private AbstractCredentialProvider pvpIdpCredentials; + + + + /** + * Sets a specific credential provider for PVP S-Profile IDP component. + * + * @param pvpIdpCredentials credential provider + */ + public void setPvpIdpCredentials(final AbstractCredentialProvider pvpIdpCredentials) { + this.pvpIdpCredentials = pvpIdpCredentials; + + } + + @Override + public boolean generateErrorMessage(final Throwable e, final HttpServletRequest request, + final HttpServletResponse response, final IRequest protocolRequest) throws Throwable { + + if (protocolRequest == null) { + throw e; + } + + if (!(protocolRequest instanceof PvpSProfilePendingRequest)) { + throw e; + } + final PvpSProfilePendingRequest pvpRequest = (PvpSProfilePendingRequest) protocolRequest; + + final Response samlResponse = Saml2Utils.createSamlObject(Response.class); + final Status status = Saml2Utils.createSamlObject(Status.class); + final StatusCode statusCode = Saml2Utils.createSamlObject(StatusCode.class); + final StatusMessage statusMessage = Saml2Utils.createSamlObject(StatusMessage.class); + + String moaError = null; + + if (e instanceof NoPassivAuthenticationException) { + statusCode.setValue(StatusCode.NO_PASSIVE_URI); + statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())); + + } else if (e instanceof NameIdFormatNotSupportedException) { + statusCode.setValue(StatusCode.INVALID_NAMEID_POLICY_URI); + statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())); + + } else if (e instanceof SloException) { + // SLOExecpetions only occurs if session information is lost + return false; + + } else if (e instanceof Pvp2Exception) { + final Pvp2Exception ex = (Pvp2Exception) e; + statusCode.setValue(ex.getStatusCodeValue()); + final String statusMessageValue = ex.getStatusMessageValue(); + if (statusMessageValue != null) { + statusMessage.setMessage(StringEscapeUtils.escapeXml(statusMessageValue)); + } + moaError = statusMessager.mapInternalErrorToExternalError(ex.getErrorId()); + + } else { + statusCode.setValue(StatusCode.RESPONDER_URI); + statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage())); + moaError = statusMessager.getResponseErrorCode(e); + } + + + if (StringUtils.isNotEmpty(moaError)) { + final StatusCode moaStatusCode = Saml2Utils.createSamlObject(StatusCode.class); + moaStatusCode.setValue(moaError); + statusCode.setStatusCode(moaStatusCode); + } + + status.setStatusCode(statusCode); + if (statusMessage.getMessage() != null) { + status.setStatusMessage(statusMessage); + } + samlResponse.setStatus(status); + final String remoteSessionID = Saml2Utils.getSecureIdentifier(); + samlResponse.setID(remoteSessionID); + + samlResponse.setIssueInstant(new DateTime()); + final Issuer nissuer = Saml2Utils.createSamlObject(Issuer.class); + nissuer.setValue(pvpBasicConfiguration.getIdpEntityId(pvpRequest.getAuthUrl())); + nissuer.setFormat(NameIDType.ENTITY); + samlResponse.setIssuer(nissuer); + + IEncoder encoder = null; + + if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + encoder = applicationContext.getBean("PVPRedirectBinding", RedirectBinding.class); + + } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { + encoder = applicationContext.getBean("PVPPOSTBinding", PostBinding.class); + + } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) { + encoder = applicationContext.getBean("PVPSOAPBinding", SoapBinding.class); + } + + if (encoder == null) { + // default to redirect binding + encoder = new RedirectBinding(); + } + + String relayState = null; + if (pvpRequest.getRequest() != null) { + relayState = pvpRequest.getRequest().getRelayState(); + } + + final X509Credential signCred = pvpIdpCredentials.getIdpAssertionSigningCredential(); + + encoder.encodeRespone(request, response, samlResponse, pvpRequest.getConsumerUrl(), relayState, + signCred, protocolRequest); + return true; + } + + @Override + public boolean validate(final HttpServletRequest request, final HttpServletResponse response, + final IRequest pending) { + + return true; + } + + protected void pvpMetadataRequest(final HttpServletRequest req, final HttpServletResponse resp) + throws EaafException { + // create pendingRequest object + final PvpSProfilePendingRequest pendingReq = + applicationContext.getBean(PvpSProfilePendingRequest.class); + pendingReq.initialize(req, authConfig); + pendingReq.setModule(getName()); + + revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP, + req.getRemoteAddr()); + + final MetadataAction metadataAction = applicationContext.getBean(MetadataAction.class); + metadataAction.processRequest(pendingReq, req, resp, null); + + } + + protected void pvpIdpPostRequest(final HttpServletRequest req, final HttpServletResponse resp) + throws EaafException { + PvpSProfilePendingRequest pendingReq = null; + + try { + // create pendingRequest object + pendingReq = applicationContext.getBean(PvpSProfilePendingRequest.class); + pendingReq.initialize(req, authConfig); + pendingReq.setModule(getName()); + + revisionsLogger.logEvent(EventConstants.SESSION_CREATED, + pendingReq.getUniqueSessionIdentifier()); + revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, + pendingReq.getUniqueTransactionIdentifier()); + revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP, + req.getRemoteAddr()); + + // get POST-Binding decoder implementation + final InboundMessage msg = (InboundMessage) new PostBinding().decode(req, resp, + metadataProvider, false, + new EaafUriCompare(pvpBasicConfiguration.getIdpSsoPostService(pendingReq.getAuthUrl()))); + pendingReq.setRequest(msg); + + // preProcess Message + preProcess(req, resp, pendingReq); + + } catch (final SecurityPolicyException e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.warn("Receive INVALID protocol request: " + samlRequest, e); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + + } catch (final SecurityException e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.warn("Receive INVALID protocol request: " + samlRequest, e); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); + + } catch (final EaafException e) { + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw e; + + } catch (final Throwable e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.warn("Receive INVALID protocol request: " + samlRequest, e); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new EaafException("pvp2.24", new Object[] {e.getMessage()}, e); + } + } + + protected void pvpIdpRedirecttRequest(final HttpServletRequest req, + final HttpServletResponse resp) throws EaafException { + PvpSProfilePendingRequest pendingReq = null; + try { + // create pendingRequest object + pendingReq = applicationContext.getBean(PvpSProfilePendingRequest.class); + pendingReq.initialize(req, authConfig); + pendingReq.setModule(getName()); + + revisionsLogger.logEvent(EventConstants.SESSION_CREATED, + pendingReq.getUniqueSessionIdentifier()); + revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, + pendingReq.getUniqueTransactionIdentifier()); + revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP, + req.getRemoteAddr()); + + // get POST-Binding decoder implementation + final InboundMessage msg = (InboundMessage) new RedirectBinding().decode(req, resp, + metadataProvider, false, new EaafUriCompare( + pvpBasicConfiguration.getIdpSsoRedirectService(pendingReq.getAuthUrl()))); + pendingReq.setRequest(msg); + + // preProcess Message + preProcess(req, resp, pendingReq); + + } catch (final SecurityPolicyException e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.warn("Receive INVALID protocol request: " + samlRequest, e); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + + } catch (final SecurityException e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.warn("Receive INVALID protocol request: " + samlRequest, e); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); + + } catch (final EaafException e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.info("Receive INVALID protocol request: " + samlRequest); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw e; + + } catch (final Throwable e) { + final String samlRequest = req.getParameter("SAMLRequest"); + log.warn("Receive INVALID protocol request: " + samlRequest, e); + + // write revision log entries + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, + pendingReq.getUniqueTransactionIdentifier()); + } + + throw new EaafException("pvp2.24", new Object[] {e.getMessage()}, e); + } + } + + + + /** + * Authentication request pre-processor. + * + * @param request http request + * @param response http response + * @param pendingReq current pending request + * @return true if preprocess can handle this request type, otherwise false + * @throws Throwable In case of an error + */ + protected abstract boolean childPreProcess(HttpServletRequest request, + HttpServletResponse response, PvpSProfilePendingRequest pendingReq) throws Throwable; + + protected void preProcess(final HttpServletRequest request, final HttpServletResponse response, + final PvpSProfilePendingRequest pendingReq) throws Throwable { + + final InboundMessage msg = pendingReq.getRequest(); + + if (StringUtils.isEmpty(msg.getEntityID())) { + throw new InvalidProtocolRequestException("pvp2.20", new Object[] {}); + + } + + if (!msg.isVerified()) { + samlVerificationEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + msg.setVerified(true); + + } + + revisionsLogger.logEvent(pendingReq, IRevisionLogger.AUTHPROTOCOL_TYPE, + getAuthProtocolIdentifier()); + + if (msg instanceof PvpSProfileRequest + && ((PvpSProfileRequest) msg).getSamlRequest() instanceof AuthnRequest) { + preProcessAuthRequest(request, response, pendingReq); + } else if (childPreProcess(request, response, pendingReq)) { + log.debug("Find protocol handler in child implementation"); + } else { + log.error("Receive unsupported PVP21 message of type: " + + ((PvpSProfileRequest) msg).getSamlRequest().getClass().getName()); + throw new InvalidPvpRequestException("pvp2.09", + new Object[] {((PvpSProfileRequest) msg).getSamlRequest().getClass().getName()}); + } + + + + // switch to session authentication + protAuthService.performAuthentication(request, response, pendingReq); + } + + + /** + * PreProcess Authn request. + * + * @param request http request + * @param response http response + * @param pendingReq current pending request + * @throws Throwable in case of an error + */ + private void preProcessAuthRequest(final HttpServletRequest request, + final HttpServletResponse response, final PvpSProfilePendingRequest pendingReq) + throws Throwable { + + final PvpSProfileRequest moaRequest = ((PvpSProfileRequest) pendingReq.getRequest()); + final SignableXMLObject samlReq = moaRequest.getSamlRequest(); + + if (!(samlReq instanceof AuthnRequest)) { + throw new InvalidPvpRequestException("Unsupported request", new Object[] {}); + } + + final EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider); + if (metadata == null) { + throw new NoMetadataInformationException(); + } + final SPSSODescriptor spSsoDescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); + + final AuthnRequest authnRequest = (AuthnRequest) samlReq; + + if (authnRequest.getIssueInstant() == null) { + log.warn("Unsupported request: No IssueInstant Attribute found."); + throw new AuthnRequestValidatorException("pvp2.22", + new Object[] {"Unsupported request: No IssueInstant Attribute found"}, pendingReq); + + } + + if (authnRequest.getIssueInstant().minusMinutes(EAAFConstants.ALLOWED_TIME_JITTER) + .isAfterNow()) { + log.warn("Unsupported request: No IssueInstant DateTime is not valid anymore."); + throw new AuthnRequestValidatorException("pvp2.22", + new Object[] {"Unsupported request: No IssueInstant DateTime is not valid anymore."}, + pendingReq); + + } + + // parse AssertionConsumerService + AssertionConsumerService consumerService = null; + if (StringUtils.isNotEmpty(authnRequest.getAssertionConsumerServiceURL()) + && StringUtils.isNotEmpty(authnRequest.getProtocolBinding())) { + // use AssertionConsumerServiceURL from request + + // check requested AssertionConsumingService URL against metadata + final List<AssertionConsumerService> metadataAssertionServiceList = + spSsoDescriptor.getAssertionConsumerServices(); + for (final AssertionConsumerService service : metadataAssertionServiceList) { + if (authnRequest.getProtocolBinding().equals(service.getBinding()) + && authnRequest.getAssertionConsumerServiceURL().equals(service.getLocation())) { + consumerService = Saml2Utils.createSamlObject(AssertionConsumerService.class); + consumerService.setBinding(authnRequest.getProtocolBinding()); + consumerService.setLocation(authnRequest.getAssertionConsumerServiceURL()); + log.debug("Requested AssertionConsumerServiceURL is valid."); + } + } + + if (consumerService == null) { + throw new InvalidAssertionConsumerServiceException( + authnRequest.getAssertionConsumerServiceURL()); + + } + + + } else { + // use AssertionConsumerServiceIndex and select consumerService from metadata + final Integer aIdx = authnRequest.getAssertionConsumerServiceIndex(); + int assertionidx = 0; + + if (aIdx != null) { + assertionidx = aIdx.intValue(); + + } else { + assertionidx = Saml2Utils.getDefaultAssertionConsumerServiceIndex(spSsoDescriptor); + + } + consumerService = spSsoDescriptor.getAssertionConsumerServices().get(assertionidx); + + if (consumerService == null) { + throw new InvalidAssertionConsumerServiceException(aIdx); + + } + } + + + // validate AuthnRequest + final AuthnRequest authReq = (AuthnRequest) samlReq; + final String oaUrl = moaRequest.getEntityMetadata(metadataProvider).getEntityID(); + log.info( + "Dispatch PVP2 AuthnRequest: OAURL=" + oaUrl + " Binding=" + consumerService.getBinding()); + + pendingReq.setSpEntityId(StringEscapeUtils.escapeHtml(oaUrl)); + pendingReq.setOnlineApplicationConfiguration( + authConfig.getServiceProviderConfiguration(pendingReq.getSpEntityId())); + pendingReq.setBinding(consumerService.getBinding()); + pendingReq.setRequest(moaRequest); + pendingReq.setConsumerUrl(consumerService.getLocation()); + + // parse AuthRequest + pendingReq.setPassiv(authReq.isPassive()); + pendingReq.setForce(authReq.isForceAuthn()); + + // AuthnRequest needs authentication + pendingReq.setNeedAuthentication(true); + + // set protocol action, which should be executed after authentication + pendingReq.setAction(AuthenticationAction.class.getName()); + + log.trace("Starting extended AuthnRequest validation and processing ... "); + authRequestValidator.validate(request, pendingReq, authReq, spSsoDescriptor); + log.debug("Extended AuthnRequest validation and processing finished"); + + // write revisionslog entry + revisionsLogger.logEvent(pendingReq, PvpEventConstants.AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST, + authReq.getID()); + + } + + @PostConstruct + private void verifyInitialization() { + if (pvpIdpCredentials == null) { + log.error("No SAML2 credentialProvider injected!"); + throw new RuntimeException("No SAML2 credentialProvider injected!"); + + } + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java index cbbed659..9378b579 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java @@ -1,35 +1,47 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.impl; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.idp.IAction; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; +import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.data.SLOInformationImpl; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvo2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.BindingNotSupportedException; +import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.AuthResponseBuilder; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.Pvp2AssertionBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import org.joda.time.DateTime; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.Assertion; @@ -45,141 +57,125 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.core.api.idp.IAction; -import at.gv.egiz.eaaf.core.api.idp.IAuthData; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface; -import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.core.impl.data.SLOInformationImpl; -import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.exception.BindingNotSupportedException; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException; -import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.AuthResponseBuilder; -import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.PVP2AssertionBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.message.PVPSProfileRequest; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - @Service("PVPAuthenticationRequestAction") public class AuthenticationAction implements IAction { - private static final Logger log = LoggerFactory.getLogger(AuthenticationAction.class); - - private static final String CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION = "protocols.pvp2.assertion.encryption.active"; - - @Autowired(required=true) private IPVPMetadataProvider metadataProvider; - @Autowired(required=true) ApplicationContext springContext; - @Autowired(required=true) IConfiguration authConfig; - @Autowired(required=true) PVP2AssertionBuilder assertionBuilder; - @Autowired(required=true) IPVP2BasicConfiguration pvpBasicConfiguration; - @Autowired(required=true) IRevisionLogger revisionsLogger; - - private AbstractCredentialProvider pvpIDPCredentials; - - /** - * Sets a specific credential provider for PVP S-Profile IDP component. - * @param pvpIDPCredentials credential provider - */ - public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) { - this.pvpIDPCredentials = pvpIDPCredentials; - - } - - @Override - public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, - HttpServletResponse httpResp, IAuthData authData) throws ResponderErrorException { - final PVPSProfilePendingRequest pvpRequest = (PVPSProfilePendingRequest) req; - try { - //get basic information - final PVPSProfileRequest moaRequest = (PVPSProfileRequest) pvpRequest.getRequest(); - final AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest(); - final EntityDescriptor peerEntity = moaRequest.getEntityMetadata(metadataProvider); - - final AssertionConsumerService consumerService = - SAML2Utils.createSAMLObject(AssertionConsumerService.class); - consumerService.setBinding(pvpRequest.getBinding()); - consumerService.setLocation(pvpRequest.getConsumerURL()); - - final DateTime date = new DateTime(); - final SLOInformationImpl sloInformation = new SLOInformationImpl(); - final String issuerEntityID = pvpBasicConfiguration.getIDPEntityId(pvpRequest.getAuthURL()); - - //build Assertion - final Assertion assertion = assertionBuilder.buildAssertion(issuerEntityID, pvpRequest, authnRequest, authData, - peerEntity, date, consumerService, sloInformation); - - final Response authResponse = AuthResponseBuilder.buildResponse( - metadataProvider, issuerEntityID, authnRequest, - date, assertion, authConfig.getBasicConfigurationBoolean( - CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION, true)); - - IEncoder binding = null; - - if (consumerService.getBinding().equals( - SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { - binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class); - - } else if (consumerService.getBinding().equals( - SAMLConstants.SAML2_POST_BINDING_URI)) { - binding = springContext.getBean("PVPPOSTBinding", PostBinding.class); - - } - - if (binding == null) { - throw new BindingNotSupportedException(consumerService.getBinding()); - } - - binding.encodeRespone(httpReq, httpResp, authResponse, - consumerService.getLocation(), moaRequest.getRelayState(), - pvpIDPCredentials.getIDPAssertionSigningCredential(), req); - - revisionsLogger.logEvent(req, 3105, authResponse.getID()); - - //set protocol type - sloInformation.setProtocolType(req.requestedModule()); - sloInformation.setSpEntityID(req.getServiceProviderConfiguration().getUniqueIdentifier()); - return sloInformation; - - } catch (MessageEncodingException | SecurityException e) { - log.warn("Message Encoding exception", e); - throw new ResponderErrorException("pvp2.01", null, e); - - } catch (final EAAFException e) { - log.info("Response generation error: Msg: ", e.getMessage()); - throw new ResponderErrorException(e.getErrorId(), e.getParams(), e); - - } catch (final Exception e) { - log.warn("Response generation error", e); - throw new ResponderErrorException("pvp2.01", null, e); - - } - - } - - @Override - public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, - HttpServletResponse httpResp) { - return true; - } - - @Override - public String getDefaultActionName() { - return "PVPAuthenticationRequestAction"; - - } - - @PostConstruct - private void verifyInitialization() { - if (pvpIDPCredentials == null) { - log.error("No SAML2 credentialProvider injected!"); - throw new RuntimeException("No SAML2 credentialProvider injected!"); - - } - } + private static final Logger log = LoggerFactory.getLogger(AuthenticationAction.class); + + private static final String CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION = + "protocols.pvp2.assertion.encryption.active"; + + @Autowired(required = true) + private IPvpMetadataProvider metadataProvider; + @Autowired(required = true) + ApplicationContext springContext; + @Autowired(required = true) + IConfiguration authConfig; + @Autowired(required = true) + Pvp2AssertionBuilder assertionBuilder; + @Autowired(required = true) + IPvo2BasicConfiguration pvpBasicConfiguration; + @Autowired(required = true) + IRevisionLogger revisionsLogger; + + private AbstractCredentialProvider pvpIdpCredentials; + + /** + * Sets a specific credential provider for PVP S-Profile IDP component. + * + * @param pvpIdpCredentials credential provider + */ + public void setPvpIdpCredentials(final AbstractCredentialProvider pvpIdpCredentials) { + this.pvpIdpCredentials = pvpIdpCredentials; + + } + + @Override + public SloInformationInterface processRequest(final IRequest req, + final HttpServletRequest httpReq, final HttpServletResponse httpResp, + final IAuthData authData) throws ResponderErrorException { + final PvpSProfilePendingRequest pvpRequest = (PvpSProfilePendingRequest) req; + try { + // get basic information + final PvpSProfileRequest moaRequest = (PvpSProfileRequest) pvpRequest.getRequest(); + final AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest(); + final EntityDescriptor peerEntity = moaRequest.getEntityMetadata(metadataProvider); + + final AssertionConsumerService consumerService = + Saml2Utils.createSamlObject(AssertionConsumerService.class); + consumerService.setBinding(pvpRequest.getBinding()); + consumerService.setLocation(pvpRequest.getConsumerUrl()); + + final DateTime date = new DateTime(); + final SLOInformationImpl sloInformation = new SLOInformationImpl(); + final String issuerEntityID = pvpBasicConfiguration.getIdpEntityId(pvpRequest.getAuthUrl()); + + // build Assertion + final Assertion assertion = assertionBuilder.buildAssertion(issuerEntityID, pvpRequest, + authnRequest, authData, peerEntity, date, consumerService, sloInformation); + + final Response authResponse = AuthResponseBuilder.buildResponse(metadataProvider, + issuerEntityID, authnRequest, date, assertion, + authConfig.getBasicConfigurationBoolean(CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION, true)); + + IEncoder binding = null; + + if (consumerService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class); + + } else if (consumerService.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { + binding = springContext.getBean("PVPPOSTBinding", PostBinding.class); + + } + + if (binding == null) { + throw new BindingNotSupportedException(consumerService.getBinding()); + } + + binding.encodeRespone(httpReq, httpResp, authResponse, consumerService.getLocation(), + moaRequest.getRelayState(), pvpIdpCredentials.getIdpAssertionSigningCredential(), req); + + revisionsLogger.logEvent(req, 3105, authResponse.getID()); + + // set protocol type + sloInformation.setProtocolType(req.requestedModule()); + sloInformation.setSpEntityID(req.getServiceProviderConfiguration().getUniqueIdentifier()); + return sloInformation; + + } catch (MessageEncodingException | SecurityException e) { + log.warn("Message Encoding exception", e); + throw new ResponderErrorException("pvp2.01", null, e); + + } catch (final EaafException e) { + log.info("Response generation error: Msg: ", e.getMessage()); + throw new ResponderErrorException(e.getErrorId(), e.getParams(), e); + + } catch (final Exception e) { + log.warn("Response generation error", e); + throw new ResponderErrorException("pvp2.01", null, e); + + } + + } + + @Override + public boolean needAuthentication(final IRequest req, final HttpServletRequest httpReq, + final HttpServletResponse httpResp) { + return true; + } + + @Override + public String getDefaultActionName() { + return "PVPAuthenticationRequestAction"; + + } + + @PostConstruct + private void verifyInitialization() { + if (pvpIdpCredentials == null) { + log.error("No SAML2 credentialProvider injected!"); + throw new RuntimeException("No SAML2 credentialProvider injected!"); + + } + } } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java index 6b957522..a1e8b5ba 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java @@ -1,123 +1,121 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.impl; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Service; - import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.IAction; import at.gv.egiz.eaaf.core.api.idp.IAuthData; -import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface; +import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; -import at.gv.egiz.eaaf.modules.pvp2.PVPEventConstants; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataBuilderConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataConfigurationFactory; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2MetadataException; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPMetadataBuilder; +import at.gv.egiz.eaaf.modules.pvp2.PvpEventConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; @Service("pvpMetadataService") public class MetadataAction implements IAction { - private static final Logger log = LoggerFactory.getLogger(MetadataAction.class); - - @Autowired private IRevisionLogger revisionsLogger; - @Autowired private PVPMetadataBuilder metadatabuilder; - @Autowired private IPVPMetadataConfigurationFactory configFactory; - - private AbstractCredentialProvider pvpIDPCredentials; - - /** - * Sets a specific credential provider for PVP S-Profile IDP component. - * @param pvpIDPCredentials credential provider - */ - public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) { - this.pvpIDPCredentials = pvpIDPCredentials; - - } - - public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, - HttpServletResponse httpResp, IAuthData authData) throws PVP2MetadataException { - try { - revisionsLogger.logEvent(req, PVPEventConstants.AUTHPROTOCOL_PVP_METADATA); - - //build metadata - IPVPMetadataBuilderConfiguration metadataConfig = - configFactory.generateMetadataBuilderConfiguration( - req.getAuthURLWithOutSlash(), - pvpIDPCredentials); - - ; - - String metadataXML = metadatabuilder.buildPVPMetadata(metadataConfig); - log.debug("METADATA: " + metadataXML); - - byte[] content = metadataXML.getBytes("UTF-8"); - httpResp.setStatus(HttpServletResponse.SC_OK); - httpResp.setContentLength(content.length); - httpResp.setContentType(MediaType.APPLICATION_XML_VALUE); - httpResp.getOutputStream().write(content); - return null; - - } catch (Exception e) { - log.error("Failed to generate metadata", e); - throw new PVP2MetadataException("pvp2.27", null); - } - } - - public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, - HttpServletResponse httpResp) { - return false; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName() - */ - @Override - public String getDefaultActionName() { - return "IDP - PVP Metadata action"; - } - - @PostConstruct - private void verifyInitialization() { - if (pvpIDPCredentials == null) { - log.error("No SAML2 credentialProvider injected!"); - throw new RuntimeException("No SAML2 credentialProvider injected!"); - - } - } - + private static final Logger log = LoggerFactory.getLogger(MetadataAction.class); + + @Autowired + private IRevisionLogger revisionsLogger; + @Autowired + private PvpMetadataBuilder metadatabuilder; + @Autowired + private IPvpMetadataConfigurationFactory configFactory; + + private AbstractCredentialProvider pvpIdpCredentials; + + /** + * Sets a specific credential provider for PVP S-Profile IDP component. + * + * @param pvpIdpCredentials credential provider + */ + public void setPvpIdpCredentials(final AbstractCredentialProvider pvpIdpCredentials) { + this.pvpIdpCredentials = pvpIdpCredentials; + + } + + @Override + public SloInformationInterface processRequest(final IRequest req, + final HttpServletRequest httpReq, final HttpServletResponse httpResp, + final IAuthData authData) throws Pvp2MetadataException { + try { + revisionsLogger.logEvent(req, PvpEventConstants.AUTHPROTOCOL_PVP_METADATA); + + // build metadata + final IPvpMetadataBuilderConfiguration metadataConfig = configFactory + .generateMetadataBuilderConfiguration(req.getAuthUrlWithOutSlash(), pvpIdpCredentials); + + + + final String metadataXml = metadatabuilder.buildPvpMetadata(metadataConfig); + log.trace("METADATA: " + metadataXml); + + final byte[] content = metadataXml.getBytes("UTF-8"); + httpResp.setStatus(HttpServletResponse.SC_OK); + httpResp.setContentLength(content.length); + httpResp.setContentType(MediaType.APPLICATION_XML_VALUE); + httpResp.getOutputStream().write(content); + return null; + + } catch (final Exception e) { + log.error("Failed to generate metadata", e); + throw new Pvp2MetadataException("pvp2.27", null); + } + } + + @Override + public boolean needAuthentication(final IRequest req, final HttpServletRequest httpReq, + final HttpServletResponse httpResp) { + return false; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName() + */ + @Override + public String getDefaultActionName() { + return "IDP - PVP Metadata action"; + } + + @PostConstruct + private void verifyInitialization() { + if (pvpIdpCredentials == null) { + log.error("No SAML2 credentialProvider injected!"); + throw new RuntimeException("No SAML2 credentialProvider injected!"); + + } + } + } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java deleted file mode 100644 index 7f086ff6..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp.impl; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; -import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage; - -@Component("PVPSProfilePendingRequest") -@Scope(value = BeanDefinition.SCOPE_PROTOTYPE) -public class PVPSProfilePendingRequest extends RequestImpl { - private static final long serialVersionUID = 4889919265919638188L; - - InboundMessage request; - String binding; - String consumerURL; - - public InboundMessage getRequest() { - return request; - } - - public void setRequest(InboundMessage request) { - this.request = request; - } - - public String getBinding() { - return binding; - } - - public void setBinding(String binding) { - this.binding = binding; - } - - public String getConsumerURL() { - return consumerURL; - } - - public void setConsumerURL(String consumerURL) { - this.consumerURL = consumerURL; - - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java new file mode 100644 index 00000000..6c621841 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.idp.impl; + +import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Component("PVPSProfilePendingRequest") +@Scope(value = BeanDefinition.SCOPE_PROTOTYPE) +public class PvpSProfilePendingRequest extends RequestImpl { + private static final long serialVersionUID = 4889919265919638188L; + + InboundMessage request; + String binding; + String consumerUrl; + + public InboundMessage getRequest() { + return request; + } + + public void setRequest(final InboundMessage request) { + this.request = request; + } + + public String getBinding() { + return binding; + } + + public void setBinding(final String binding) { + this.binding = binding; + } + + public String getConsumerUrl() { + return consumerUrl; + } + + public void setConsumerUrl(final String consumerUrl) { + this.consumerUrl = consumerUrl; + + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java index 07423c19..bf51ac0f 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java @@ -1,41 +1,35 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder; import java.util.ArrayList; import java.util.List; - +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; import org.joda.time.DateTime; -import org.opensaml.Configuration; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.EncryptedAssertion; import org.opensaml.saml2.core.Issuer; -import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.NameIDType; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.encryption.Encrypter; @@ -57,97 +51,111 @@ import org.opensaml.xml.security.x509.X509Credential; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - /** + * Authentication response builder. + * * @author tlenz * */ public class AuthResponseBuilder { - private static final Logger log = LoggerFactory.getLogger(AuthResponseBuilder.class); - - public static Response buildResponse(MetadataProvider metadataProvider, String issuerEntityID, RequestAbstractType req, DateTime date, Assertion assertion, boolean enableEncryption) throws InvalidAssertionEncryptionException { - Response authResponse = SAML2Utils.createSAMLObject(Response.class); - - Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); - - nissuer.setValue(issuerEntityID); - nissuer.setFormat(NameID.ENTITY); - authResponse.setIssuer(nissuer); - authResponse.setInResponseTo(req.getID()); - - //set responseID - String remoteSessionID = SAML2Utils.getSecureIdentifier(); - authResponse.setID(remoteSessionID); - - - //SAML2 response required IssueInstant - authResponse.setIssueInstant(date); - - authResponse.setStatus(SAML2Utils.getSuccessStatus()); - - //check, if metadata includes an encryption key - MetadataCredentialResolver mdCredResolver = - new MetadataCredentialResolver(metadataProvider); - - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) ); - criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); - criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) ); - - X509Credential encryptionCredentials = null; - try { - encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet); - - } catch (SecurityException e2) { - log.warn("Can not extract the Assertion Encryption-Key from metadata", e2); - throw new InvalidAssertionEncryptionException(); - - } - - if (encryptionCredentials != null && enableEncryption) { - //encrypt SAML2 assertion - - try { - - EncryptionParameters dataEncParams = new EncryptionParameters(); - dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE); - - List<KeyEncryptionParameters> keyEncParamList = new ArrayList<KeyEncryptionParameters>(); - KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters(); - - keyEncParam.setEncryptionCredential(encryptionCredentials); - keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE); - KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration() - .getKeyInfoGeneratorManager().getDefaultManager() - .getFactory(encryptionCredentials); - keyEncParam.setKeyInfoGenerator(kigf.newInstance()); - keyEncParamList.add(keyEncParam); - - Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList); - //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE); - samlEncrypter.setKeyPlacement(KeyPlacement.PEER); - - EncryptedAssertion encryptAssertion = null; - - encryptAssertion = samlEncrypter.encrypt(assertion); - - authResponse.getEncryptedAssertions().add(encryptAssertion); - - } catch (EncryptionException e1) { - log.warn("Can not encrypt the PVP2 assertion", e1); - throw new InvalidAssertionEncryptionException(); - - } - - } else { - authResponse.getAssertions().add(assertion); - - } - - return authResponse; - } + private static final Logger log = LoggerFactory.getLogger(AuthResponseBuilder.class); + + /** + * Build PVP2 S-Profile authentication response. + * + * @param metadataProvider Service-Provider metadata + * @param issuerEntityID IDP entityId + * @param req current pending request + * @param date Timestamp + * @param assertion PVP2 S-Profil Assertion + * @param enableEncryption encrypt Assertion flag + * @return PVP2 S-Profile authentication response + * @throws InvalidAssertionEncryptionException In case of an error + */ + public static Response buildResponse(final MetadataProvider metadataProvider, + final String issuerEntityID, final RequestAbstractType req, final DateTime date, + final Assertion assertion, final boolean enableEncryption) + throws InvalidAssertionEncryptionException { + final Response authResponse = Saml2Utils.createSamlObject(Response.class); + + final Issuer nissuer = Saml2Utils.createSamlObject(Issuer.class); + + nissuer.setValue(issuerEntityID); + nissuer.setFormat(NameIDType.ENTITY); + authResponse.setIssuer(nissuer); + authResponse.setInResponseTo(req.getID()); + + // set responseID + final String remoteSessionID = Saml2Utils.getSecureIdentifier(); + authResponse.setID(remoteSessionID); + + + // SAML2 response required IssueInstant + authResponse.setIssueInstant(date); + + authResponse.setStatus(Saml2Utils.getSuccessStatus()); + + // check, if metadata includes an encryption key + final MetadataCredentialResolver mdCredResolver = + new MetadataCredentialResolver(metadataProvider); + + final CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new EntityIDCriteria(req.getIssuer().getValue())); + criteriaSet + .add(new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS)); + criteriaSet.add(new UsageCriteria(UsageType.ENCRYPTION)); + + X509Credential encryptionCredentials = null; + try { + encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet); + + } catch (final SecurityException e2) { + log.warn("Can not extract the Assertion Encryption-Key from metadata", e2); + throw new InvalidAssertionEncryptionException(); + + } + + if (encryptionCredentials != null && enableEncryption) { + // encrypt SAML2 assertion + + try { + + final EncryptionParameters dataEncParams = new EncryptionParameters(); + dataEncParams.setAlgorithm(PvpConstants.DEFAULT_SYM_ENCRYPTION_METHODE); + + final List<KeyEncryptionParameters> keyEncParamList = new ArrayList<>(); + final KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters(); + + keyEncParam.setEncryptionCredential(encryptionCredentials); + keyEncParam.setAlgorithm(PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE); + final KeyInfoGeneratorFactory kigf = + org.opensaml.xml.Configuration.getGlobalSecurityConfiguration() + .getKeyInfoGeneratorManager().getDefaultManager().getFactory(encryptionCredentials); + keyEncParam.setKeyInfoGenerator(kigf.newInstance()); + keyEncParamList.add(keyEncParam); + + final Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList); + // samlEncrypter.setKeyPlacement(KeyPlacement.INLINE); + samlEncrypter.setKeyPlacement(KeyPlacement.PEER); + + EncryptedAssertion encryptAssertion = null; + + encryptAssertion = samlEncrypter.encrypt(assertion); + + authResponse.getEncryptedAssertions().add(encryptAssertion); + + } catch (final EncryptionException e1) { + log.warn("Can not encrypt the PVP2 assertion", e1); + throw new InvalidAssertionEncryptionException(); + + } + + } else { + authResponse.getAssertions().add(assertion); + + } + + return authResponse; + } } diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java deleted file mode 100644 index 2ccc2c9e..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java +++ /dev/null @@ -1,459 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder; - -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.core.Assertion; -import org.opensaml.saml2.core.Attribute; -import org.opensaml.saml2.core.AttributeQuery; -import org.opensaml.saml2.core.AttributeStatement; -import org.opensaml.saml2.core.Audience; -import org.opensaml.saml2.core.AudienceRestriction; -import org.opensaml.saml2.core.AuthnContext; -import org.opensaml.saml2.core.AuthnContextClassRef; -import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.core.AuthnStatement; -import org.opensaml.saml2.core.Conditions; -import org.opensaml.saml2.core.Issuer; -import org.opensaml.saml2.core.NameID; -import org.opensaml.saml2.core.RequestedAuthnContext; -import org.opensaml.saml2.core.Subject; -import org.opensaml.saml2.core.SubjectConfirmation; -import org.opensaml.saml2.core.SubjectConfirmationData; -import org.opensaml.saml2.core.impl.AuthnRequestImpl; -import org.opensaml.saml2.metadata.AssertionConsumerService; -import org.opensaml.saml2.metadata.AttributeConsumingService; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.NameIDFormat; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.Base64Utils; - -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper; -import at.gv.egiz.eaaf.core.api.idp.IAuthData; -import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; -import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface; -import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException; -import at.gv.egiz.eaaf.core.impl.data.Pair; -import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; -import at.gv.egiz.eaaf.core.impl.utils.Random; -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.QAANotSupportedException; -import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.UnprovideableAttributeException; -import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPAttributeBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QAALevelVerifier; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - -@Service("PVP2AssertionBuilder") -public class PVP2AssertionBuilder implements PVPConstants { - - private static final Logger log = LoggerFactory.getLogger(PVP2AssertionBuilder.class); - @Autowired private ILoALevelMapper loaLevelMapper; - @Autowired private ISubjectNameIdGenerator subjectNameIdGenerator; - - - /** - * Build a PVP assertion as response for a SAML2 AttributeQuery request - * - * @param issuerEntityID EnitiyID, which should be used for this IDP response - * @param attrQuery AttributeQuery request from Service-Provider - * @param attrList List of PVP response attributes - * @param now Current time - * @param validTo ValidTo time of the assertion - * @param qaaLevel QAA level of the authentication - * @param sessionIndex SAML2 SessionIndex, which should be included * - * @return PVP 2.1 Assertion - * @throws PVP2Exception - */ - public Assertion buildAssertion(String issuerEntityID, AttributeQuery attrQuery, - List<Attribute> attrList, DateTime now, DateTime validTo, String qaaLevel, String sessionIndex) throws PVP2Exception { - - AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - authnContextClassRef.setAuthnContextClassRef(qaaLevel); - - NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat()); - subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue()); - - SubjectConfirmationData subjectConfirmationData = null; - - return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now, - authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, - validTo); - } - - - /** - * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest - * - * @param issuerEntityID EnitiyID, which should be used for this IDP response - * @param pendingReq Current processed pendingRequest DAO - * @param authnRequest Current processed PVP AuthnRequest - * @param authData AuthenticationData of the user, which is already authenticated - * @param peerEntity SAML2 EntityDescriptor of the service-provider, which receives the response - * @param date TimeStamp - * @param assertionConsumerService SAML2 endpoint of the service-provider, which should be used - * @param sloInformation Single LogOut information DAO - * @return - * @throws PVP2Exception - */ - public Assertion buildAssertion(String issuerEntityID, PVPSProfilePendingRequest pendingReq, AuthnRequest authnRequest, - IAuthData authData, EntityDescriptor peerEntity, DateTime date, - AssertionConsumerService assertionConsumerService, SLOInformationInterface sloInformation) - throws PVP2Exception { - - ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration(); - AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - - //check if authn. request contains LoA - RequestedAuthnContext reqAuthnContext = authnRequest.getRequestedAuthnContext(); - if (reqAuthnContext == null) { - authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel()); - - } else { - //authn. request requests LoA levels. To LoA validation - List<AuthnContextClassRef> reqAuthnContextClassRefIt = reqAuthnContext.getAuthnContextClassRefs(); - - //get matching mode from authn. request - String loaMatchingMode = EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM; - if (reqAuthnContext.getComparison() != null && - StringUtils.isNotEmpty(reqAuthnContext.getComparison().toString())) - loaMatchingMode = reqAuthnContext.getComparison().toString(); - - //get requested LoAs - if (reqAuthnContextClassRefIt.size() == 0) { - QAALevelVerifier.verifyQAALevel(authData.getEIDASQAALevel(), - oaParam.getRequiredLoA(), loaMatchingMode); - authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel()); - - } else { - List<String> eIDASLoaFromRequest = new ArrayList<String>(); - for (AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) { - String qaa_uri = authnClassRef.getAuthnContextClassRef(); - - if (!qaa_uri.trim().startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) { - if (loaLevelMapper != null) { - log.debug("Find no eIDAS LoA in AuthnReq. Start mapping process ... " ); - eIDASLoaFromRequest.add(loaLevelMapper.mapToeIDASLoA(qaa_uri.trim())); - - } else - log.debug("AuthnRequest contains no eIDAS LoA. NO LoA mapper FOUND, ignore " - + "'" + qaa_uri.trim() + "'"); - } else - eIDASLoaFromRequest.add(qaa_uri.trim()); - - } - - //stop process if no supported LoA scheme is requested - if (eIDASLoaFromRequest.isEmpty()) { - log.info("Authn. request contains no supported LoA level. Stop authentication process ... "); - throw new QAANotSupportedException("No supported LoA in Authn. request"); - - } - - //verifiy LoAs from request to authentication LoA - QAALevelVerifier.verifyQAALevel(authData.getEIDASQAALevel(), eIDASLoaFromRequest , loaMatchingMode); - authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel()); - - } - } - - - //load SPSS decriptor from service-provider metadata - SPSSODescriptor spSSODescriptor = peerEntity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); - - //add Attributes to Assertion - List<Attribute> attrList = new ArrayList<Attribute>(); - if (spSSODescriptor.getAttributeConsumingServices() != null && - spSSODescriptor.getAttributeConsumingServices().size() > 0) { - - Integer aIdx = authnRequest.getAttributeConsumingServiceIndex(); - int idx = 0; - - AttributeConsumingService attributeConsumingService = null; - if (aIdx != null) { - idx = aIdx.intValue(); - attributeConsumingService = spSSODescriptor - .getAttributeConsumingServices().get(idx); - - } else { - List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices(); - for (AttributeConsumingService el : attrConsumingServiceList) { - if (el.isDefault()) - attributeConsumingService = el; - } - } - - /* - * TODO: maybe use first AttributeConsumingService if no is selected - * in request or on service is marked as default - * - */ - if (attributeConsumingService == null ) { - List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices(); - if (attrConsumingServiceList != null && !attrConsumingServiceList.isEmpty()) - attributeConsumingService = attrConsumingServiceList.get(0); - - } - - - if (attributeConsumingService != null) { - Iterator<RequestedAttribute> it = attributeConsumingService - .getRequestAttributes().iterator(); - while (it.hasNext()) { - RequestedAttribute reqAttribut = it.next(); - try { - Attribute attr = PVPAttributeBuilder.buildAttribute( - reqAttribut.getName(), oaParam, authData); - if (attr == null) { - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - } else { - attrList.add(attr); - } - - } catch (UnavailableAttributeException e) { - log.info( - "Attribute generation for " - + reqAttribut.getFriendlyName() + " not possible."); - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - - - } catch (PVP2Exception e) { - log.info( - "Attribute generation failed! for " - + reqAttribut.getFriendlyName()); - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - - } catch (Exception e) { - log.warn( - "General Attribute generation failed! for " - + reqAttribut.getFriendlyName(), e); - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - - } - } - } - } - - //generate subjectNameId - NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - Pair<String, String> subjectNameIdPair = subjectNameIdGenerator.generateSubjectNameId(authData, oaParam); - subjectNameID.setValue(subjectNameIdPair.getFirst()); - subjectNameID.setNameQualifier(subjectNameIdPair.getSecond()); - - //get NameIDFormat from request - String nameIDFormat = NameID.TRANSIENT; - AuthnRequest authnReq = (AuthnRequestImpl) authnRequest; - if (authnReq.getNameIDPolicy() != null && - StringUtils.isNotEmpty(authnReq.getNameIDPolicy().getFormat())) { - nameIDFormat = authnReq.getNameIDPolicy().getFormat(); - - } else { - //get NameIDFormat from metadata - List<NameIDFormat> metadataNameIDFormats = spSSODescriptor.getNameIDFormats(); - - if (metadataNameIDFormats != null) { - - for (NameIDFormat el : metadataNameIDFormats) { - if (NameID.PERSISTENT.equals(el.getFormat())) { - nameIDFormat = NameID.PERSISTENT; - break; - - } else if (NameID.TRANSIENT.equals(el.getFormat()) || - NameID.UNSPECIFIED.equals(el.getFormat())) - break; - - } - } - } - - if (NameID.TRANSIENT.equals(nameIDFormat) || NameID.UNSPECIFIED.equals(nameIDFormat)) { - String random = Random.nextHexRandom32(); - String nameID = subjectNameID.getValue(); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1")); - subjectNameID.setValue(Base64Utils.encodeToString(hash)); - subjectNameID.setNameQualifier(null); - subjectNameID.setFormat(NameID.TRANSIENT); - - } catch (Exception e) { - log.warn("PVP2 subjectNameID error", e); - throw new ResponderErrorException("internal.03", null, e); - - } - - } else - subjectNameID.setFormat(nameIDFormat); - - - String sessionIndex = null; - - //if request is a reauthentication and NameIDFormat match reuse old session information - if (StringUtils.isNotEmpty(authData.getNameID()) && - StringUtils.isNotEmpty(authData.getNameIDFormat()) && - nameIDFormat.equals(authData.getNameIDFormat())) { - subjectNameID.setValue(authData.getNameID()); - sessionIndex = authData.getSessionIndex(); - - } - - // - if (StringUtils.isEmpty(sessionIndex)) - sessionIndex = SAML2Utils.getSecureIdentifier(); - - SubjectConfirmationData subjectConfirmationData = SAML2Utils - .createSAMLObject(SubjectConfirmationData.class); - subjectConfirmationData.setInResponseTo(authnRequest.getID()); - subjectConfirmationData.setNotOnOrAfter(new DateTime(authData.getSsoSessionValidTo().getTime())); - - //set 'recipient' attribute in subjectConformationData - subjectConfirmationData.setRecipient(assertionConsumerService.getLocation()); - - //set IP address of the user machine as 'Address' attribute in subjectConformationData - String usersIPAddress = pendingReq.getRawData( - RequestImpl.DATAID_REQUESTER_IP_ADDRESS, String.class); - if (StringUtils.isNotEmpty(usersIPAddress)) - subjectConfirmationData.setAddress(usersIPAddress); - - //set SLO information - sloInformation.setUserNameIdentifier(subjectNameID.getValue()); - sloInformation.setNameIDFormat(subjectNameID.getFormat()); - sloInformation.setSessionIndex(sessionIndex); - - return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter()); - } - - /** - * - * @param issuer IDP EntityID - * @param entityID Service Provider EntityID - * @param date - * @param authnContextClassRef - * @param attrList - * @param subjectNameID - * @param subjectConfirmationData - * @param sessionIndex - * @param isValidTo - * @return - * @throws ConfigurationException - */ - - public Assertion buildGenericAssertion(String issuer, String entityID, DateTime date, - AuthnContextClassRef authnContextClassRef, List<Attribute> attrList, - NameID subjectNameID, SubjectConfirmationData subjectConfirmationData, - String sessionIndex, DateTime isValidTo) throws ResponderErrorException { - Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class); - - AuthnContext authnContext = SAML2Utils - .createSAMLObject(AuthnContext.class); - authnContext.setAuthnContextClassRef(authnContextClassRef); - - AuthnStatement authnStatement = SAML2Utils - .createSAMLObject(AuthnStatement.class); - - authnStatement.setAuthnInstant(date); - authnStatement.setSessionIndex(sessionIndex); - authnStatement.setAuthnContext(authnContext); - - assertion.getAuthnStatements().add(authnStatement); - - AttributeStatement attributeStatement = SAML2Utils - .createSAMLObject(AttributeStatement.class); - attributeStatement.getAttributes().addAll(attrList); - if (attributeStatement.getAttributes().size() > 0) { - assertion.getAttributeStatements().add(attributeStatement); - } - - Subject subject = SAML2Utils.createSAMLObject(Subject.class); - subject.setNameID(subjectNameID); - - SubjectConfirmation subjectConfirmation = SAML2Utils - .createSAMLObject(SubjectConfirmation.class); - subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); - subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData); - - subject.getSubjectConfirmations().add(subjectConfirmation); - - Conditions conditions = SAML2Utils.createSAMLObject(Conditions.class); - AudienceRestriction audienceRestriction = SAML2Utils - .createSAMLObject(AudienceRestriction.class); - Audience audience = SAML2Utils.createSAMLObject(Audience.class); - - audience.setAudienceURI(entityID); - audienceRestriction.getAudiences().add(audience); - conditions.setNotBefore(date); - conditions.setNotOnOrAfter(isValidTo); - - conditions.getAudienceRestrictions().add(audienceRestriction); - - assertion.setConditions(conditions); - - Issuer issuerObj = SAML2Utils.createSAMLObject(Issuer.class); - - if (issuer.endsWith("/")) - issuer = issuer.substring(0, issuer.length()-1); - issuerObj.setValue(issuer); - issuerObj.setFormat(NameID.ENTITY); - - assertion.setIssuer(issuerObj); - assertion.setSubject(subject); - assertion.setID(SAML2Utils.getSecureIdentifier()); - assertion.setIssueInstant(date); - - return assertion; - } -} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java new file mode 100644 index 00000000..79de4567 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java @@ -0,0 +1,465 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder; + +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +import at.gv.egiz.eaaf.core.api.idp.IspConfiguration; +import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface; +import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; +import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.QaaNotSupportedException; +import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator; +import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException; +import at.gv.egiz.eaaf.modules.pvp2.idp.exception.UnprovideableAttributeException; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QaaLevelVerifier; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeQuery; +import org.opensaml.saml2.core.AttributeStatement; +import org.opensaml.saml2.core.Audience; +import org.opensaml.saml2.core.AudienceRestriction; +import org.opensaml.saml2.core.AuthnContext; +import org.opensaml.saml2.core.AuthnContextClassRef; +import org.opensaml.saml2.core.AuthnRequest; +import org.opensaml.saml2.core.AuthnStatement; +import org.opensaml.saml2.core.Conditions; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.core.RequestedAuthnContext; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.SubjectConfirmation; +import org.opensaml.saml2.core.SubjectConfirmationData; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.AttributeConsumingService; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.NameIDFormat; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.Base64Utils; + +@Service("PVP2AssertionBuilder") +public class Pvp2AssertionBuilder implements PvpConstants { + + private static final Logger log = LoggerFactory.getLogger(Pvp2AssertionBuilder.class); + @Autowired + private ILoALevelMapper loaLevelMapper; + @Autowired + private ISubjectNameIdGenerator subjectNameIdGenerator; + + + /** + * Build a PVP assertion as response for a SAML2 AttributeQuery request. + * + * @param issuerEntityID EnitiyID, which should be used for this IDP response + * @param attrQuery AttributeQuery request from Service-Provider + * @param attrList List of PVP response attributes + * @param now Current time + * @param validTo ValidTo time of the assertion + * @param qaaLevel QAA level of the authentication + * @param sessionIndex SAML2 SessionIndex, which should be included * + * @return PVP 2.1 Assertion + * @throws Pvp2Exception In case of an error + */ + public Assertion buildAssertion(final String issuerEntityID, final AttributeQuery attrQuery, + final List<Attribute> attrList, final DateTime now, final DateTime validTo, + final String qaaLevel, final String sessionIndex) throws Pvp2Exception { + + final AuthnContextClassRef authnContextClassRef = + Saml2Utils.createSamlObject(AuthnContextClassRef.class); + authnContextClassRef.setAuthnContextClassRef(qaaLevel); + + final NameID subjectNameID = Saml2Utils.createSamlObject(NameID.class); + subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat()); + subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue()); + + final SubjectConfirmationData subjectConfirmationData = null; + + return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now, + authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, + validTo); + } + + + /** + * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest. + * + * @param issuerEntityID EnitiyID, which should be used for this IDP response + * @param pendingReq Current processed pendingRequest DAO + * @param authnRequest Current processed PVP AuthnRequest + * @param authData AuthenticationData of the user, which is already authenticated + * @param peerEntity SAML2 EntityDescriptor of the service-provider, which receives the response + * @param date TimeStamp + * @param assertionConsumerService SAML2 endpoint of the service-provider, which should be used + * @param sloInformation Single LogOut information DAO + * @return PVP2 S-Profil Assertion + * @throws Pvp2Exception In case of an error + */ + public Assertion buildAssertion(final String issuerEntityID, + final PvpSProfilePendingRequest pendingReq, final AuthnRequest authnRequest, + final IAuthData authData, final EntityDescriptor peerEntity, final DateTime date, + final AssertionConsumerService assertionConsumerService, + final SloInformationInterface sloInformation) throws Pvp2Exception { + + final IspConfiguration oaParam = pendingReq.getServiceProviderConfiguration(); + final AuthnContextClassRef authnContextClassRef = + Saml2Utils.createSamlObject(AuthnContextClassRef.class); + + // check if authn. request contains LoA + final RequestedAuthnContext reqAuthnContext = authnRequest.getRequestedAuthnContext(); + if (reqAuthnContext == null) { + authnContextClassRef.setAuthnContextClassRef(authData.getEidasQaaLevel()); + + } else { + // authn. request requests LoA levels. To LoA validation + final List<AuthnContextClassRef> reqAuthnContextClassRefIt = + reqAuthnContext.getAuthnContextClassRefs(); + + // get matching mode from authn. request + String loaMatchingMode = EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM; + if (reqAuthnContext.getComparison() != null + && StringUtils.isNotEmpty(reqAuthnContext.getComparison().toString())) { + loaMatchingMode = reqAuthnContext.getComparison().toString(); + } + + // get requested LoAs + if (reqAuthnContextClassRefIt.size() == 0) { + QaaLevelVerifier.verifyQaaLevel(authData.getEidasQaaLevel(), oaParam.getRequiredLoA(), + loaMatchingMode); + authnContextClassRef.setAuthnContextClassRef(authData.getEidasQaaLevel()); + + } else { + final List<String> eidasLoaFromRequest = new ArrayList<>(); + for (final AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) { + final String qaa_uri = authnClassRef.getAuthnContextClassRef(); + + if (!qaa_uri.trim().startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) { + if (loaLevelMapper != null) { + log.debug("Find no eIDAS LoA in AuthnReq. Start mapping process ... "); + eidasLoaFromRequest.add(loaLevelMapper.mapToeIDASLoA(qaa_uri.trim())); + + } else { + log.debug("AuthnRequest contains no eIDAS LoA. NO LoA mapper FOUND, ignore " + "'" + + qaa_uri.trim() + "'"); + } + } else { + eidasLoaFromRequest.add(qaa_uri.trim()); + } + + } + + // stop process if no supported LoA scheme is requested + if (eidasLoaFromRequest.isEmpty()) { + log.info( + "Authn. request contains no supported LoA level. Stop authentication process ... "); + throw new QaaNotSupportedException("No supported LoA in Authn. request"); + + } + + // verifiy LoAs from request to authentication LoA + QaaLevelVerifier.verifyQaaLevel(authData.getEidasQaaLevel(), eidasLoaFromRequest, + loaMatchingMode); + authnContextClassRef.setAuthnContextClassRef(authData.getEidasQaaLevel()); + + } + } + + + // load SPSS decriptor from service-provider metadata + final SPSSODescriptor spSsoDescriptor = peerEntity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); + + // add Attributes to Assertion + final List<Attribute> attrList = new ArrayList<>(); + if (spSsoDescriptor.getAttributeConsumingServices() != null + && spSsoDescriptor.getAttributeConsumingServices().size() > 0) { + + final Integer aIdx = authnRequest.getAttributeConsumingServiceIndex(); + int idx = 0; + + AttributeConsumingService attributeConsumingService = null; + if (aIdx != null) { + idx = aIdx.intValue(); + attributeConsumingService = spSsoDescriptor.getAttributeConsumingServices().get(idx); + + } else { + final List<AttributeConsumingService> attrConsumingServiceList = + spSsoDescriptor.getAttributeConsumingServices(); + for (final AttributeConsumingService el : attrConsumingServiceList) { + if (el.isDefault()) { + attributeConsumingService = el; + } + } + } + + /* + * TODO: maybe use first AttributeConsumingService if no is selected in request or on service + * is marked as default + * + */ + if (attributeConsumingService == null) { + final List<AttributeConsumingService> attrConsumingServiceList = + spSsoDescriptor.getAttributeConsumingServices(); + if (attrConsumingServiceList != null && !attrConsumingServiceList.isEmpty()) { + attributeConsumingService = attrConsumingServiceList.get(0); + } + + } + + + if (attributeConsumingService != null) { + final Iterator<RequestedAttribute> it = + attributeConsumingService.getRequestAttributes().iterator(); + while (it.hasNext()) { + final RequestedAttribute reqAttribut = it.next(); + try { + final Attribute attr = + PvpAttributeBuilder.buildAttribute(reqAttribut.getName(), oaParam, authData); + if (attr == null) { + if (reqAttribut.isRequired()) { + throw new UnprovideableAttributeException(reqAttribut.getName()); + } + } else { + attrList.add(attr); + } + + } catch (final UnavailableAttributeException e) { + log.info( + "Attribute generation for " + reqAttribut.getFriendlyName() + " not possible."); + if (reqAttribut.isRequired()) { + throw new UnprovideableAttributeException(reqAttribut.getName()); + } + + + } catch (final Pvp2Exception e) { + log.info("Attribute generation failed! for " + reqAttribut.getFriendlyName()); + if (reqAttribut.isRequired()) { + throw new UnprovideableAttributeException(reqAttribut.getName()); + } + + } catch (final Exception e) { + log.warn("General Attribute generation failed! for " + reqAttribut.getFriendlyName(), + e); + if (reqAttribut.isRequired()) { + throw new UnprovideableAttributeException(reqAttribut.getName()); + } + + } + } + } + } + + // generate subjectNameId + final NameID subjectNameID = Saml2Utils.createSamlObject(NameID.class); + final Pair<String, String> subjectNameIdPair = + subjectNameIdGenerator.generateSubjectNameId(authData, oaParam); + subjectNameID.setValue(subjectNameIdPair.getFirst()); + subjectNameID.setNameQualifier(subjectNameIdPair.getSecond()); + + // get NameIDFormat from request + String nameIdFormat = NameIDType.TRANSIENT; + final AuthnRequest authnReq = authnRequest; + if (authnReq.getNameIDPolicy() != null + && StringUtils.isNotEmpty(authnReq.getNameIDPolicy().getFormat())) { + nameIdFormat = authnReq.getNameIDPolicy().getFormat(); + + } else { + // get NameIDFormat from metadata + final List<NameIDFormat> metadataNameIdFormats = spSsoDescriptor.getNameIDFormats(); + + if (metadataNameIdFormats != null) { + + for (final NameIDFormat el : metadataNameIdFormats) { + if (NameIDType.PERSISTENT.equals(el.getFormat())) { + nameIdFormat = NameIDType.PERSISTENT; + break; + + } else if (NameIDType.TRANSIENT.equals(el.getFormat()) + || NameIDType.UNSPECIFIED.equals(el.getFormat())) { + break; + } + + } + } + } + + if (NameIDType.TRANSIENT.equals(nameIdFormat) || NameIDType.UNSPECIFIED.equals(nameIdFormat)) { + final String random = Random.nextHexRandom32(); + final String nameID = subjectNameID.getValue(); + + try { + final MessageDigest md = MessageDigest.getInstance("SHA-1"); + final byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1")); + subjectNameID.setValue(Base64Utils.encodeToString(hash)); + subjectNameID.setNameQualifier(null); + subjectNameID.setFormat(NameIDType.TRANSIENT); + + } catch (final Exception e) { + log.warn("PVP2 subjectNameID error", e); + throw new ResponderErrorException("internal.03", null, e); + + } + + } else { + subjectNameID.setFormat(nameIdFormat); + } + + + String sessionIndex = null; + + // if request is a reauthentication and NameIDFormat match reuse old session information + if (StringUtils.isNotEmpty(authData.getNameID()) + && StringUtils.isNotEmpty(authData.getNameIdFormat()) + && nameIdFormat.equals(authData.getNameIdFormat())) { + subjectNameID.setValue(authData.getNameID()); + sessionIndex = authData.getSessionIndex(); + + } + + // + if (StringUtils.isEmpty(sessionIndex)) { + sessionIndex = Saml2Utils.getSecureIdentifier(); + } + + final SubjectConfirmationData subjectConfirmationData = + Saml2Utils.createSamlObject(SubjectConfirmationData.class); + subjectConfirmationData.setInResponseTo(authnRequest.getID()); + subjectConfirmationData + .setNotOnOrAfter(new DateTime(authData.getSsoSessionValidTo().getTime())); + + // set 'recipient' attribute in subjectConformationData + subjectConfirmationData.setRecipient(assertionConsumerService.getLocation()); + + // set IP address of the user machine as 'Address' attribute in subjectConformationData + final String usersIpAddress = + pendingReq.getRawData(RequestImpl.DATAID_REQUESTER_IP_ADDRESS, String.class); + if (StringUtils.isNotEmpty(usersIpAddress)) { + subjectConfirmationData.setAddress(usersIpAddress); + } + + // set SLO information + sloInformation.setUserNameIdentifier(subjectNameID.getValue()); + sloInformation.setNameIdFormat(subjectNameID.getFormat()); + sloInformation.setSessionIndex(sessionIndex); + + return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date, + authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, + subjectConfirmationData.getNotOnOrAfter()); + } + + /** + * Build generic part of PVP S-Profile Assertion. + * + * @param issuer IDP EntityID + * @param entityID Service Provider EntityID + * @param date Timestamp + * @param authnContextClassRef SAML2 AuthnContextClassReference + * @param attrList List of attributes + * @param subjectNameID SubjectNameId + * @param subjectConfirmationData SubjectConfirmationInformation + * @param sessionIndex SessionIndex + * @param isValidTo ValidTo Timestamp + * @return PVP S-Profile Assertion + * @throws ConfigurationException In case on an error + */ + + public Assertion buildGenericAssertion(String issuer, final String entityID, final DateTime date, + final AuthnContextClassRef authnContextClassRef, final List<Attribute> attrList, + final NameID subjectNameID, final SubjectConfirmationData subjectConfirmationData, + final String sessionIndex, final DateTime isValidTo) throws ResponderErrorException { + final Assertion assertion = Saml2Utils.createSamlObject(Assertion.class); + + final AuthnContext authnContext = Saml2Utils.createSamlObject(AuthnContext.class); + authnContext.setAuthnContextClassRef(authnContextClassRef); + + final AuthnStatement authnStatement = Saml2Utils.createSamlObject(AuthnStatement.class); + + authnStatement.setAuthnInstant(date); + authnStatement.setSessionIndex(sessionIndex); + authnStatement.setAuthnContext(authnContext); + + assertion.getAuthnStatements().add(authnStatement); + + final AttributeStatement attributeStatement = + Saml2Utils.createSamlObject(AttributeStatement.class); + attributeStatement.getAttributes().addAll(attrList); + if (attributeStatement.getAttributes().size() > 0) { + assertion.getAttributeStatements().add(attributeStatement); + } + + final Subject subject = Saml2Utils.createSamlObject(Subject.class); + subject.setNameID(subjectNameID); + + final SubjectConfirmation subjectConfirmation = + Saml2Utils.createSamlObject(SubjectConfirmation.class); + subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); + subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData); + + subject.getSubjectConfirmations().add(subjectConfirmation); + + final Conditions conditions = Saml2Utils.createSamlObject(Conditions.class); + final AudienceRestriction audienceRestriction = + Saml2Utils.createSamlObject(AudienceRestriction.class); + final Audience audience = Saml2Utils.createSamlObject(Audience.class); + + audience.setAudienceURI(entityID); + audienceRestriction.getAudiences().add(audience); + conditions.setNotBefore(date); + conditions.setNotOnOrAfter(isValidTo); + + conditions.getAudienceRestrictions().add(audienceRestriction); + + assertion.setConditions(conditions); + + final Issuer issuerObj = Saml2Utils.createSamlObject(Issuer.class); + + if (issuer.endsWith("/")) { + issuer = issuer.substring(0, issuer.length() - 1); + } + issuerObj.setValue(issuer); + issuerObj.setFormat(NameIDType.ENTITY); + + assertion.setIssuer(issuerObj); + assertion.setSubject(subject); + assertion.setID(Saml2Utils.getSecureIdentifier()); + assertion.setIssueInstant(date); + + return assertion; + } +} diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider index cda12a62..c3c68e20 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider @@ -1 +1 @@ -at.gv.egiz.eaaf.modules.pvp2.idp.PVP2SProfileIDPSpringResourceProvider
\ No newline at end of file +at.gv.egiz.eaaf.modules.pvp2.idp.Pvp2SProfileIdpSpringResourceProvider
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml index b01a09ff..d29b5aba 100644 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml @@ -1,22 +1,19 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- - --> - <beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xmlns:tx="http://www.springframework.org/schema/tx" - xmlns:aop="http://www.springframework.org/schema/aop" - xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd - http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> - - <bean id="PVP2AssertionBuilder" - class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.PVP2AssertionBuilder" /> - - <bean id="PVPSProfilePendingRequest" - class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest" - scope="prototype"/> - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> + + <bean id="PVP2AssertionBuilder" + class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.Pvp2AssertionBuilder" /> + + <bean id="PVPSProfilePendingRequest" + class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest" + scope="prototype" /> + </beans>
\ No newline at end of file diff --git a/eaaf_modules/eaaf_module_pvp2_sp/pom.xml b/eaaf_modules/eaaf_module_pvp2_sp/pom.xml index b3e11151..51219563 100644 --- a/eaaf_modules/eaaf_module_pvp2_sp/pom.xml +++ b/eaaf_modules/eaaf_module_pvp2_sp/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>at.gv.egiz.eaaf</groupId> <artifactId>eaaf_modules</artifactId> - <version>1.0.14-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> </parent> <artifactId>eaaf_module_pvp2_sp</artifactId> <name>eaaf_module_pvp2_sp</name> diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/api/IPVPAuthnRequestBuilderConfiguruation.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/api/IPVPAuthnRequestBuilderConfiguruation.java deleted file mode 100644 index b8a8e796..00000000 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/api/IPVPAuthnRequestBuilderConfiguruation.java +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.sp.api; - -import java.util.List; - -import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.xml.security.credential.Credential; -import org.w3c.dom.Element; - -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; - -/** - * @author tlenz - * - */ -public interface IPVPAuthnRequestBuilderConfiguruation { - - /** - * Defines a unique name for this PVP Service-provider, which is used for logging - * - * @return - */ - public String getSPNameForLogging(); - - /** - * If true, the SAML2 isPassive flag is set in the AuthnRequest - * - * @return - */ - public Boolean isPassivRequest(); - - /** - * Define the ID of the AssertionConsumerService, - * which defines the required attributes in service-provider metadata. - * - * @return - */ - public Integer getAssertionConsumerServiceId(); - - /** - * Define the SAML2 EntityID of the service provider. - * - * @return - */ - public String getSPEntityID(); - - /** - * Define the SAML2 NameIDPolicy - * - * @return Service-Provider EntityID, but never null - */ - public String getNameIDPolicyFormat(); - - /** - * Define the AuthnContextClassRefernece of this request - * - * Example: - * http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-3 - * http://www.stork.gov.eu/1.0/citizenQAALevel/4 - * - * - * @return - */ - public String getAuthnContextClassRef(); - - /** - * Define the AuthnContextComparison model, which should be used - * - * @return - */ - public AuthnContextComparisonTypeEnumeration getAuthnContextComparison(); - - - /** - * Define the credential, which should be used to sign the AuthnRequest - * - * @return - */ - public Credential getAuthnRequestSigningCredential(); - - - /** - * Define the SAML2 EntityDescriptor of the IDP, which should receive the AuthnRequest - * - * @return Credential, but never null. - */ - public EntityDescriptor getIDPEntityDescriptor(); - - /** - * Set the SAML2 NameIDPolicy allow-creation flag - * - * @return EntityDescriptor, but never null. - */ - public boolean getNameIDPolicyAllowCreation(); - - - /** - * Set the requested SubjectNameID - * - * @return SubjectNameID, or null if no SubjectNameID should be used - */ - public String getSubjectNameID(); - - /** - * Define the qualifier of the <code>SubjectNameID</code> - * <br><br> - * Like: 'urn:publicid:gv.at:cdid+BF' - * - * @return qualifier, or null if no qualifier should be set - */ - public String getSubjectNameIDQualifier(); - - /** - * Define the format of the subjectNameID, which is included in authn-request - * - * - * @return nameIDFormat, of SAML2 'transient' if nothing is defined - */ - public String getSubjectNameIDFormat(); - - /** - * Define a SP specific SAML2 requestID - * - * @return requestID, or null if the requestID should be generated automatically - */ - public String getRequestID(); - - /** - * Defines the 'method' attribute in 'SubjectConformation' element - * - * @return method, or null if no method should set - */ - public String getSubjectConformationMethode(); - - /** - * Define the information, which should be added as 'subjectConformationDate' - * in 'SubjectConformation' element - * - * @return subjectConformation information or null if no subjectConformation should be set - */ - public Element getSubjectConformationDate(); - - - /** - * Get the EntityId of the SP in case of a SAML2 proxy use-case - * - * @return - */ - public String getScopeRequesterId(); - - - /** - * Get a FriendlyName for the SP that sends the request - * - * @return - */ - public String getProviderName(); - - - /** - * Get a Set of SAML2 attributes that are requested by using SAML2 requested attributes - * <br> - * <b>Info:</b> Attributes are requested by using eIDAS SAML2 extension for requested attributes - * - * @return - */ - public List<EAAFRequestedAttribute> getRequestedAttributes(); - -} diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/api/IPvpAuthnRequestBuilderConfiguruation.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/api/IPvpAuthnRequestBuilderConfiguruation.java new file mode 100644 index 00000000..d050dd4b --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/api/IPvpAuthnRequestBuilderConfiguruation.java @@ -0,0 +1,187 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.sp.api; + +import java.util.List; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.xml.security.credential.Credential; +import org.w3c.dom.Element; + +/** + * Configuration of a PVP2 S-Profile authentication-request builder. + * + * @author tlenz + * + */ +public interface IPvpAuthnRequestBuilderConfiguruation { + + /** + * Defines a unique name for this PVP Service-provider, which is used for logging. + * + * @return + */ + public String getSpNameForLogging(); + + /** + * If true, the SAML2 isPassive flag is set in the AuthnRequest. + * + * @return + */ + public Boolean isPassivRequest(); + + /** + * Define the ID of the AssertionConsumerService, which defines the required attributes in + * service-provider metadata. + * + * @return + */ + public Integer getAssertionConsumerServiceId(); + + /** + * Define the SAML2 EntityID of the service provider. + * + * @return + */ + public String getSpEntityID(); + + /** + * Define the SAML2 NameIDPolicy. + * + * @return Service-Provider EntityID, but never null + */ + public String getNameIdPolicyFormat(); + + /** + * Define the AuthnContextClassRefernece of this request. + * + *<p> + * Example: http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-3 + * http://www.stork.gov.eu/1.0/citizenQAALevel/4 + *</p> + * + * @return + */ + public String getAuthnContextClassRef(); + + /** + * Define the AuthnContextComparison model, which should be used. + * + * @return + */ + public AuthnContextComparisonTypeEnumeration getAuthnContextComparison(); + + + /** + * Define the credential, which should be used to sign the AuthnRequest. + * + * @return + */ + public Credential getAuthnRequestSigningCredential(); + + + /** + * Define the SAML2 EntityDescriptor of the IDP, which should receive the AuthnRequest. + * + * @return Credential, but never null. + */ + public EntityDescriptor getIdpEntityDescriptor(); + + /** + * Set the SAML2 NameIDPolicy allow-creation flag. + * + * @return EntityDescriptor, but never null. + */ + public boolean getNameIdPolicyAllowCreation(); + + + /** + * Set the requested SubjectNameID. + * + * @return SubjectNameID, or null if no SubjectNameID should be used + */ + public String getSubjectNameID(); + + /** + * Define the qualifier of the <code>SubjectNameID</code> <br> + * <br> + * Like: 'urn:publicid:gv.at:cdid+BF' + * + * @return qualifier, or null if no qualifier should be set + */ + public String getSubjectNameIdQualifier(); + + /** + * Define the format of the subjectNameID, which is included in authn-request. + * + * + * @return nameIDFormat, of SAML2 'transient' if nothing is defined + */ + public String getSubjectNameIdFormat(); + + /** + * Define a SP specific SAML2 requestID. + * + * @return requestID, or null if the requestID should be generated automatically + */ + public String getRequestID(); + + /** + * Defines the 'method' attribute in 'SubjectConformation' element. + * + * @return method, or null if no method should set + */ + public String getSubjectConformationMethode(); + + /** + * Define the information, which should be added as 'subjectConformationDate' in + * 'SubjectConformation' element. + * + * @return subjectConformation information or null if no subjectConformation should be set + */ + public Element getSubjectConformationDate(); + + + /** + * Get the EntityId of the SP in case of a SAML2 proxy use-case. + * + * @return + */ + public String getScopeRequesterId(); + + + /** + * Get a FriendlyName for the SP that sends the request. + * + * @return + */ + public String getProviderName(); + + + /** + * Get a Set of SAML2 attributes that are requested by using SAML2 requested attributes. <br> + * <b>Info:</b> Attributes are requested by using eIDAS SAML2 extension for requested attributes + * + * @return + */ + public List<EaafRequestedAttribute> getRequestedAttributes(); + +} diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionAttributeExtractorExeption.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionAttributeExtractorExeption.java index 3afcc65d..4411d9c6 100644 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionAttributeExtractorExeption.java +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionAttributeExtractorExeption.java @@ -1,56 +1,40 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.sp.exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; -/** - * @author tlenz - * - */ -public class AssertionAttributeExtractorExeption extends PVP2Exception { - - /** - * - */ - private static final long serialVersionUID = -6459000942830951492L; - - public AssertionAttributeExtractorExeption(String attributeName) { - super("Parse PVP2.1 assertion FAILED: Attribute " + attributeName - + " can not extract.", null); - } - - public AssertionAttributeExtractorExeption(String messageId, - Object[] parameters) { - super(messageId, parameters); - } - - public AssertionAttributeExtractorExeption() { - super("Parse PVP2.1 assertion FAILED. Interfederation not possible", null); - } +public class AssertionAttributeExtractorExeption extends Pvp2Exception { + + private static final long serialVersionUID = -6459000942830951492L; + + public AssertionAttributeExtractorExeption(final String attributeName) { + super("Parse PVP2.1 assertion FAILED: Attribute " + attributeName + " can not extract.", null); + } + + public AssertionAttributeExtractorExeption(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + + public AssertionAttributeExtractorExeption() { + super("Parse PVP2.1 assertion FAILED. Interfederation not possible", null); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionValidationExeption.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionValidationExeption.java index 5766aab0..1096c535 100644 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionValidationExeption.java +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AssertionValidationExeption.java @@ -1,53 +1,38 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.sp.exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; -/** - * @author tlenz - * - */ -public class AssertionValidationExeption extends PVP2Exception { - - private static final long serialVersionUID = -3987805399122286259L; - - public AssertionValidationExeption(String messageId, Object[] parameters) { - super(messageId, parameters); - } - - /** - * @param string - * @param object - * @param e - */ - public AssertionValidationExeption(String string, Object[] parameters, - Throwable e) { - super(string, parameters, e); - } + +public class AssertionValidationExeption extends Pvp2Exception { + + private static final long serialVersionUID = -3987805399122286259L; + + public AssertionValidationExeption(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + + public AssertionValidationExeption(final String string, final Object[] parameters, + final Throwable e) { + super(string, parameters, e); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnRequestBuildException.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnRequestBuildException.java index 9fdffaf4..5ad42fb7 100644 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnRequestBuildException.java +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnRequestBuildException.java @@ -1,53 +1,37 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. + */ + package at.gv.egiz.eaaf.modules.pvp2.sp.exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; -/** - * @author tlenz - * - */ -public class AuthnRequestBuildException extends PVP2Exception { - - /** - * - */ - private static final long serialVersionUID = -1375451065455859354L; - - /** - * @param messageId - * @param parameters - */ - public AuthnRequestBuildException(String messageId, Object[] parameters) { - super(messageId, parameters); - } - - public AuthnRequestBuildException(String messageId, Object[] parameters, Throwable e) { - super(messageId, parameters, e); - } + +public class AuthnRequestBuildException extends Pvp2Exception { + + + private static final long serialVersionUID = -1375451065455859354L; + + public AuthnRequestBuildException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + + public AuthnRequestBuildException(final String messageId, final Object[] parameters, final Throwable e) { + super(messageId, parameters, e); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnResponseValidationException.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnResponseValidationException.java index 9d2ec046..d8d7683c 100644 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnResponseValidationException.java +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/exception/AuthnResponseValidationException.java @@ -1,54 +1,39 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.sp.exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; -/** - * @author tlenz - * - */ -public class AuthnResponseValidationException extends PVP2Exception { - - /** - * - */ - private static final long serialVersionUID = 8023812861029406575L; - - /** - * @param messageId - * @param parameters - */ - public AuthnResponseValidationException(String messageId, Object[] parameters) { - super(messageId, parameters); - } - - public AuthnResponseValidationException(String messageId, Object[] parameters, Throwable e) { - super(messageId, parameters, e); - } + +public class AuthnResponseValidationException extends Pvp2Exception { + + + private static final long serialVersionUID = 8023812861029406575L; + + + public AuthnResponseValidationException(final String messageId, final Object[] parameters) { + super(messageId, parameters); + } + + public AuthnResponseValidationException(final String messageId, final Object[] parameters, final Throwable e) { + super(messageId, parameters, e); + } } diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PVPAuthnRequestBuilder.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PVPAuthnRequestBuilder.java deleted file mode 100644 index e8cdd1f7..00000000 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PVPAuthnRequestBuilder.java +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.sp.impl; - -import java.security.NoSuchAlgorithmException; -import java.util.List; - -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.opensaml.common.impl.SecureRandomIdentifierGenerator; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.common.Extensions; -import org.opensaml.saml2.core.AuthnContextClassRef; -import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; -import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.core.Issuer; -import org.opensaml.saml2.core.NameID; -import org.opensaml.saml2.core.NameIDPolicy; -import org.opensaml.saml2.core.NameIDType; -import org.opensaml.saml2.core.RequestedAuthnContext; -import org.opensaml.saml2.core.RequesterID; -import org.opensaml.saml2.core.Scoping; -import org.opensaml.saml2.core.Subject; -import org.opensaml.saml2.core.SubjectConfirmation; -import org.opensaml.saml2.core.SubjectConfirmationData; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.SingleSignOnService; -import org.opensaml.ws.message.encoder.MessageEncodingException; -import org.opensaml.xml.security.SecurityException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Service; - -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; -import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttributes; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EAAFRequestExtensionBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; -import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPVPAuthnRequestBuilderConfiguruation; -import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException; - -/** - * @author tlenz - * - */ -@Service("pvpAuthnRequestBuilder") -public class PVPAuthnRequestBuilder { - private static final Logger log = LoggerFactory.getLogger(PVPAuthnRequestBuilder.class); - - - @Autowired(required=true) ApplicationContext springContext; - - - /** - * Build a PVP2.x specific authentication request - * - * @param pendingReq Currently processed pendingRequest - * @param config AuthnRequest builder configuration, never null - * @param idpEntity SAML2 EntityDescriptor of the IDP, which receive this AuthnRequest, never null - * @param httpResp - * @throws NoSuchAlgorithmException - * @throws SecurityException - * @throws PVP2Exception - * @throws MessageEncodingException - */ - public void buildAuthnRequest(IRequest pendingReq, IPVPAuthnRequestBuilderConfiguruation config, - HttpServletResponse httpResp) throws NoSuchAlgorithmException, MessageEncodingException, PVP2Exception, SecurityException { - //get IDP Entity element from config - EntityDescriptor idpEntity = config.getIDPEntityDescriptor(); - - AuthnRequest authReq = SAML2Utils - .createSAMLObject(AuthnRequest.class); - - //select SingleSignOn Service endpoint from IDP metadata - SingleSignOnService endpoint = null; - for (SingleSignOnService sss : - idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) { - - // use POST binding as default if it exists - if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { - endpoint = sss; - - } else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) - && endpoint == null ) - endpoint = sss; - - } - - if (endpoint == null) { - log.warn("Building AuthnRequest FAILED: > Requested IDP " + idpEntity.getEntityID() - + " does not support POST or Redirect Binding."); - throw new AuthnRequestBuildException("sp.pvp2.00", new Object[]{config.getSPNameForLogging(), idpEntity.getEntityID()}); - - } else - authReq.setDestination(endpoint.getLocation()); - - - //set basic AuthnRequest information - String reqID = config.getRequestID(); - if (StringUtils.isNotEmpty(reqID)) - authReq.setID(reqID); - - else { - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - authReq.setID(gen.generateIdentifier()); - - } - - authReq.setIssueInstant(new DateTime()); - - //set isPassive flag - if (config.isPassivRequest() == null) - authReq.setIsPassive(false); - else - authReq.setIsPassive(config.isPassivRequest()); - - //set EntityID of the service provider - Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); - issuer.setFormat(NameIDType.ENTITY); - issuer.setValue(config.getSPEntityID()); - authReq.setIssuer(issuer); - - //set AssertionConsumerService ID - if (config.getAssertionConsumerServiceId() != null) - authReq.setAssertionConsumerServiceIndex(config.getAssertionConsumerServiceId()); - - //set NameIDPolicy - if (config.getNameIDPolicyFormat() != null) { - NameIDPolicy policy = SAML2Utils.createSAMLObject(NameIDPolicy.class); - policy.setAllowCreate(config.getNameIDPolicyAllowCreation()); - policy.setFormat(config.getNameIDPolicyFormat()); - authReq.setNameIDPolicy(policy); - } - - //set requested QAA level - if (config.getAuthnContextClassRef() != null) { - RequestedAuthnContext reqAuthContext = SAML2Utils.createSAMLObject(RequestedAuthnContext.class); - AuthnContextClassRef authnClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - - authnClassRef.setAuthnContextClassRef(config.getAuthnContextClassRef()); - - if (config.getAuthnContextComparison() == null) - reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); - else - reqAuthContext.setComparison(config.getAuthnContextComparison()); - - reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); - authReq.setRequestedAuthnContext(reqAuthContext); - } - - //set request Subject element - if (StringUtils.isNotEmpty(config.getSubjectNameID())) { - Subject reqSubject = SAML2Utils.createSAMLObject(Subject.class); - NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - - subjectNameID.setValue(config.getSubjectNameID()); - if (StringUtils.isNotEmpty(config.getSubjectNameIDQualifier())) - subjectNameID.setNameQualifier(config.getSubjectNameIDQualifier()); - - if (StringUtils.isNotEmpty(config.getSubjectNameIDFormat())) - subjectNameID.setFormat(config.getSubjectNameIDFormat()); - else - subjectNameID.setFormat(NameID.TRANSIENT); - - reqSubject.setNameID(subjectNameID); - - if (config.getSubjectConformationDate() != null) { - SubjectConfirmation subjectConformation = SAML2Utils.createSAMLObject(SubjectConfirmation.class); - SubjectConfirmationData subjectConformDate = SAML2Utils.createSAMLObject(SubjectConfirmationData.class); - subjectConformation.setSubjectConfirmationData(subjectConformDate); - reqSubject.getSubjectConfirmations().add(subjectConformation ); - - if (config.getSubjectConformationMethode() != null) - subjectConformation.setMethod(config.getSubjectConformationMethode()); - - subjectConformDate.setDOM(config.getSubjectConformationDate()); - - } - - authReq.setSubject(reqSubject ); - - } - - - //set ProviderName - if (StringUtils.isNotEmpty(config.getProviderName())) - authReq.setProviderName(config.getProviderName()); - - //set RequesterId in case of proxy mode - if (StringUtils.isNotEmpty(config.getScopeRequesterId())) { - Scoping scope = SAML2Utils.createSAMLObject(Scoping.class); - RequesterID requesterId = SAML2Utils.createSAMLObject(RequesterID.class); - requesterId.setRequesterID(config.getScopeRequesterId()); - scope.getRequesterIDs().add(requesterId ); - authReq.setScoping(scope ); - - } - - //add optional requested attributes - if (config.getRequestedAttributes() != null) { - List<EAAFRequestedAttribute> reqAttr = config.getRequestedAttributes(); - Extensions extenstions = new EAAFRequestExtensionBuilder().buildObject(); - EAAFRequestedAttributes reqAttributs = SAML2Utils.createSAMLObject(EAAFRequestedAttributes.class); - reqAttributs.getAttributes().addAll(reqAttr); - extenstions.getUnknownXMLObjects().add(reqAttributs); - authReq.setExtensions(extenstions ); - - } - - //select message encoder - IEncoder binding = null; - if (endpoint.getBinding().equals( - SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { - binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class); - - } else if (endpoint.getBinding().equals( - SAMLConstants.SAML2_POST_BINDING_URI)) { - binding = springContext.getBean("PVPPOSTBinding", PostBinding.class); - - } - - //encode message - binding.encodeRequest(null, httpResp, authReq, - endpoint.getLocation(), pendingReq.getPendingRequestId(), config.getAuthnRequestSigningCredential(), pendingReq); - } - -} diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java new file mode 100644 index 00000000..36f43cc8 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java @@ -0,0 +1,263 @@ +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.gv.egiz.eaaf.modules.pvp2.sp.impl; + +import java.security.NoSuchAlgorithmException; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestExtensionBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPvpAuthnRequestBuilderConfiguruation; +import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.opensaml.common.impl.SecureRandomIdentifierGenerator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.common.Extensions; +import org.opensaml.saml2.core.AuthnContextClassRef; +import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; +import org.opensaml.saml2.core.AuthnRequest; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.NameIDPolicy; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.core.RequestedAuthnContext; +import org.opensaml.saml2.core.RequesterID; +import org.opensaml.saml2.core.Scoping; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.SubjectConfirmation; +import org.opensaml.saml2.core.SubjectConfirmationData; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.xml.security.SecurityException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +/** + * PVP2 S-Profil Authentication-Request builder-implementation. + * + * @author tlenz + * + */ +@Service("pvpAuthnRequestBuilder") +public class PvpAuthnRequestBuilder { + private static final Logger log = LoggerFactory.getLogger(PvpAuthnRequestBuilder.class); + + + @Autowired(required = true) + ApplicationContext springContext; + + + /** + * Build a PVP2.x specific authentication request + * + * @param pendingReq Currently processed pendingRequest + * @param config AuthnRequest builder configuration, never null + * @param httpResp http response object + * @throws NoSuchAlgorithmException In case of error + * @throws SecurityException In case of error + * @throws Pvp2Exception In case of error + * @throws MessageEncodingException In case of error + */ + public void buildAuthnRequest(final IRequest pendingReq, + final IPvpAuthnRequestBuilderConfiguruation config, final HttpServletResponse httpResp) + throws NoSuchAlgorithmException, MessageEncodingException, Pvp2Exception, SecurityException { + // get IDP Entity element from config + final EntityDescriptor idpEntity = config.getIdpEntityDescriptor(); + + final AuthnRequest authReq = Saml2Utils.createSamlObject(AuthnRequest.class); + + // select SingleSignOn Service endpoint from IDP metadata + SingleSignOnService endpoint = null; + for (final SingleSignOnService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) + .getSingleSignOnServices()) { + + // use POST binding as default if it exists + if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { + endpoint = sss; + + } else if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) + && endpoint == null) { + endpoint = sss; + } + + } + + if (endpoint == null) { + log.warn("Building AuthnRequest FAILED: > Requested IDP " + idpEntity.getEntityID() + + " does not support POST or Redirect Binding."); + throw new AuthnRequestBuildException("sp.pvp2.00", + new Object[] {config.getSpNameForLogging(), idpEntity.getEntityID()}); + + } else { + authReq.setDestination(endpoint.getLocation()); + } + + + // set basic AuthnRequest information + final String reqID = config.getRequestID(); + if (StringUtils.isNotEmpty(reqID)) { + authReq.setID(reqID); + } else { + final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + authReq.setID(gen.generateIdentifier()); + + } + + authReq.setIssueInstant(new DateTime()); + + // set isPassive flag + if (config.isPassivRequest() == null) { + authReq.setIsPassive(false); + } else { + authReq.setIsPassive(config.isPassivRequest()); + } + + // set EntityID of the service provider + final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class); + issuer.setFormat(NameIDType.ENTITY); + issuer.setValue(config.getSpEntityID()); + authReq.setIssuer(issuer); + + // set AssertionConsumerService ID + if (config.getAssertionConsumerServiceId() != null) { + authReq.setAssertionConsumerServiceIndex(config.getAssertionConsumerServiceId()); + } + + // set NameIDPolicy + if (config.getNameIdPolicyFormat() != null) { + final NameIDPolicy policy = Saml2Utils.createSamlObject(NameIDPolicy.class); + policy.setAllowCreate(config.getNameIdPolicyAllowCreation()); + policy.setFormat(config.getNameIdPolicyFormat()); + authReq.setNameIDPolicy(policy); + } + + // set requested QAA level + if (config.getAuthnContextClassRef() != null) { + final RequestedAuthnContext reqAuthContext = + Saml2Utils.createSamlObject(RequestedAuthnContext.class); + final AuthnContextClassRef authnClassRef = + Saml2Utils.createSamlObject(AuthnContextClassRef.class); + + authnClassRef.setAuthnContextClassRef(config.getAuthnContextClassRef()); + + if (config.getAuthnContextComparison() == null) { + reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); + } else { + reqAuthContext.setComparison(config.getAuthnContextComparison()); + } + + reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); + authReq.setRequestedAuthnContext(reqAuthContext); + } + + // set request Subject element + if (StringUtils.isNotEmpty(config.getSubjectNameID())) { + final Subject reqSubject = Saml2Utils.createSamlObject(Subject.class); + final NameID subjectNameID = Saml2Utils.createSamlObject(NameID.class); + + subjectNameID.setValue(config.getSubjectNameID()); + if (StringUtils.isNotEmpty(config.getSubjectNameIdQualifier())) { + subjectNameID.setNameQualifier(config.getSubjectNameIdQualifier()); + } + + if (StringUtils.isNotEmpty(config.getSubjectNameIdFormat())) { + subjectNameID.setFormat(config.getSubjectNameIdFormat()); + } else { + subjectNameID.setFormat(NameIDType.TRANSIENT); + } + + reqSubject.setNameID(subjectNameID); + + if (config.getSubjectConformationDate() != null) { + final SubjectConfirmation subjectConformation = + Saml2Utils.createSamlObject(SubjectConfirmation.class); + final SubjectConfirmationData subjectConformDate = + Saml2Utils.createSamlObject(SubjectConfirmationData.class); + subjectConformation.setSubjectConfirmationData(subjectConformDate); + reqSubject.getSubjectConfirmations().add(subjectConformation); + + if (config.getSubjectConformationMethode() != null) { + subjectConformation.setMethod(config.getSubjectConformationMethode()); + } + + subjectConformDate.setDOM(config.getSubjectConformationDate()); + + } + + authReq.setSubject(reqSubject); + + } + + + // set ProviderName + if (StringUtils.isNotEmpty(config.getProviderName())) { + authReq.setProviderName(config.getProviderName()); + } + + // set RequesterId in case of proxy mode + if (StringUtils.isNotEmpty(config.getScopeRequesterId())) { + final Scoping scope = Saml2Utils.createSamlObject(Scoping.class); + final RequesterID requesterId = Saml2Utils.createSamlObject(RequesterID.class); + requesterId.setRequesterID(config.getScopeRequesterId()); + scope.getRequesterIDs().add(requesterId); + authReq.setScoping(scope); + + } + + // add optional requested attributes + if (config.getRequestedAttributes() != null) { + final List<EaafRequestedAttribute> reqAttr = config.getRequestedAttributes(); + final Extensions extenstions = new EaafRequestExtensionBuilder().buildObject(); + final EaafRequestedAttributes reqAttributs = + Saml2Utils.createSamlObject(EaafRequestedAttributes.class); + reqAttributs.getAttributes().addAll(reqAttr); + extenstions.getUnknownXMLObjects().add(reqAttributs); + authReq.setExtensions(extenstions); + + } + + // select message encoder + IEncoder binding = null; + if (endpoint.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class); + + } else if (endpoint.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { + binding = springContext.getBean("PVPPOSTBinding", PostBinding.class); + + } + + // encode message + binding.encodeRequest(null, httpResp, authReq, endpoint.getLocation(), + pendingReq.getPendingRequestId(), config.getAuthnRequestSigningCredential(), pendingReq); + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/utils/AssertionAttributeExtractor.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/utils/AssertionAttributeExtractor.java index 22f1cb06..e0cad257 100644 --- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/utils/AssertionAttributeExtractor.java +++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/utils/AssertionAttributeExtractor.java @@ -1,29 +1,22 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.sp.impl.utils; import java.util.ArrayList; @@ -34,7 +27,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; - +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AssertionAttributeExtractorExeption; import org.apache.commons.lang3.StringUtils; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.Attribute; @@ -48,295 +42,316 @@ import org.opensaml.xml.XMLObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AssertionAttributeExtractorExeption; - public class AssertionAttributeExtractor { - - private static final Logger log = LoggerFactory.getLogger(AssertionAttributeExtractor.class); - - private Assertion assertion = null; - private Map<String, List<String>> attributs = new HashMap<String, List<String>>(); - //private PersonalAttributeList storkAttributes = new PersonalAttributeList(); - - private final List<String> minimalMDSAttributeNamesList = Arrays.asList( - PVPConstants.PRINCIPAL_NAME_NAME, - PVPConstants.GIVEN_NAME_NAME, - PVPConstants.BIRTHDATE_NAME, - PVPConstants.BPK_NAME); - - private final List<String> minimalIDLAttributeNamesList = Arrays.asList( - PVPConstants.EID_IDENTITY_LINK_NAME, - PVPConstants.EID_SOURCE_PIN_NAME, - PVPConstants.EID_SOURCE_PIN_TYPE_NAME); - - /** - * Parse the SAML2 Response element and extracts included information - * <br><br> - * <b>INFO:</b> Actually, only the first SAML2 Assertion of the SAML2 Response is used! - * - * @param samlResponse SAML2 Response - * @throws AssertionAttributeExtractorExeption - */ - public AssertionAttributeExtractor(StatusResponseType samlResponse) throws AssertionAttributeExtractorExeption { - if (samlResponse != null && samlResponse instanceof Response) { - List<Assertion> assertions = ((Response) samlResponse).getAssertions(); - if (assertions.size() == 0) - throw new AssertionAttributeExtractorExeption("Assertion"); - - else if (assertions.size() > 1) - log.warn("Found more then ONE PVP2.1 assertions. Only the First is used."); - - assertion = assertions.get(0); - internalInitialize(); - - } else - throw new AssertionAttributeExtractorExeption(); - } - - /** - * Parse the SAML2 Assertion element and extracts included information - * <br><br> - * - * @param assertion SAML2 Assertion - * @throws AssertionAttributeExtractorExeption - */ - public AssertionAttributeExtractor(Assertion assertion) throws AssertionAttributeExtractorExeption { - this.assertion = assertion; - internalInitialize(); - - } - - /** - * Get all SAML2 attributes from first SAML2 AttributeStatement element - * - * @return List of SAML2 Attributes - */ - public List<Attribute> getAllResponseAttributesFromFirstAttributeStatement() { - return assertion.getAttributeStatements().get(0).getAttributes(); - - } - - /** - * Get all SAML2 attributes of specific SAML2 AttributeStatement element - * - * @param attrStatementID List ID of the AttributeStatement element - * @return List of SAML2 Attributes - */ - public List<Attribute> getAllResponseAttributes(int attrStatementID) { - return assertion.getAttributeStatements().get(attrStatementID).getAttributes(); - - } - - /** - * check attributes from assertion with minimal required attribute list - * @return - */ - public boolean containsAllRequiredAttributes() { - return containsAllRequiredAttributes(minimalMDSAttributeNamesList) - || containsAllRequiredAttributes(minimalIDLAttributeNamesList); - - } - - /** - * check attributes from assertion with attributeNameList - * bPK or enc_bPK are always needed - * - * @param List of attributes which are required - * - * @return - */ - public boolean containsAllRequiredAttributes(Collection<String> attributeNameList) { - - //first check if a bPK or an encrypted bPK is available - boolean flag = true; - for (String attr : attributeNameList) { - if (!attributs.containsKey(attr)) { - flag = false; - log.debug("Assertion contains no Attribute " + attr); - - } - - } - - if (flag) - return flag; - - else { - log.debug("Assertion contains no all minimum attributes from: " + attributeNameList.toString()); - return false; - - } - } - - public boolean containsAttribute(String attributeName) { - return attributs.containsKey(attributeName); - - } - - public String getSingleAttributeValue(String attributeName) { - if (attributs.containsKey(attributeName) && attributs.get(attributeName).size() > 0) - return attributs.get(attributeName).get(0); - else - return null; - - } - - public List<String> getAttributeValues(String attributeName) { - return attributs.get(attributeName); - - } - - /** - * Return all include PVP attribute names - * - * @return - */ - public Set<String> getAllIncludeAttributeNames() { - return attributs.keySet(); - - } - -// public PersonalAttributeList getSTORKAttributes() { -// return storkAttributes; -// } - - - public String getNameID() throws AssertionAttributeExtractorExeption { - if (assertion.getSubject() != null) { - Subject subject = assertion.getSubject(); - - if (subject.getNameID() != null) { - if (StringUtils.isNotEmpty(subject.getNameID().getValue())) - return subject.getNameID().getValue(); - - else - log.error("SAML2 NameID Element is empty."); - } - } - - throw new AssertionAttributeExtractorExeption("nameID"); - } - - /** - * Get the Id attribute from SAML2 assertion - * - * @return - */ - public String getAssertionID() { - return assertion.getID(); - - } - - public String getSessionIndex() throws AssertionAttributeExtractorExeption { - AuthnStatement authn = getAuthnStatement(); - - if (StringUtils.isNotEmpty(authn.getSessionIndex())) - return authn.getSessionIndex(); - - else - throw new AssertionAttributeExtractorExeption("SessionIndex"); - } - - /** - * @return - * @throws AssertionAttributeExtractorExeption - */ - public String getQAALevel() throws AssertionAttributeExtractorExeption { - AuthnStatement authn = getAuthnStatement(); - if (authn.getAuthnContext() != null && authn.getAuthnContext().getAuthnContextClassRef() != null) { - AuthnContextClassRef qaaClass = authn.getAuthnContext().getAuthnContextClassRef(); - - if (StringUtils.isNotEmpty(qaaClass.getAuthnContextClassRef())) - return qaaClass.getAuthnContextClassRef(); - - else - throw new AssertionAttributeExtractorExeption("AuthnContextClassRef (QAALevel)"); - } - - throw new AssertionAttributeExtractorExeption("AuthnContextClassRef"); - } - - public Assertion getFullAssertion() { - return assertion; - } - - - /** - * Get the Assertion validTo period - * - * Primarily, the 'SessionNotOnOrAfter' attribute in the SAML2 'AuthnStatment' element is used. - * If this is empty, this method returns value of SAML 'Conditions' element. - * - * @return Date, until this SAML2 assertion is valid - */ - public Date getAssertionNotOnOrAfter() { - if (getFullAssertion().getAuthnStatements() != null - && getFullAssertion().getAuthnStatements().size() > 0) { - for (AuthnStatement el : getFullAssertion().getAuthnStatements()) { - if (el.getSessionNotOnOrAfter() != null) - return (el.getSessionNotOnOrAfter().toDate()); - } - - } - - return getFullAssertion().getConditions().getNotOnOrAfter().toDate(); - - } - - /** - * Get the Assertion validFrom period - * - * This method returns value of SAML 'Conditions' element. - * - * @return Date, after this SAML2 assertion is valid, otherwise null - */ - public Date getAssertionNotBefore() { - try { - return getFullAssertion().getConditions().getNotBefore().toDate(); - - } catch (NullPointerException e) { - return null; - - } - - } - - private AuthnStatement getAuthnStatement() throws AssertionAttributeExtractorExeption { - List<AuthnStatement> authnList = assertion.getAuthnStatements(); - if (authnList.size() == 0) - throw new AssertionAttributeExtractorExeption("AuthnStatement"); - - else if (authnList.size() > 1) - log.warn("Found more then ONE AuthnStatements in PVP2.1 assertions. Only the First is used."); - - return authnList.get(0); - } - - private void internalInitialize() { - if (assertion.getAttributeStatements() != null && - assertion.getAttributeStatements().size() > 0) { - AttributeStatement attrStat = assertion.getAttributeStatements().get(0); - for (Attribute attr : attrStat.getAttributes()) { - if (attr.getName().startsWith(PVPConstants.STORK_ATTRIBUTE_PREFIX)) { - List<String> storkAttrValues = new ArrayList<String>(); - for (XMLObject el : attr.getAttributeValues()) - storkAttrValues.add(el.getDOM().getTextContent()); - -// PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(), -// false, storkAttrValues , "Available"); -// storkAttributes.put(attr.getName(), storkAttr ); - - } else { - List<String> attrList = new ArrayList<String>(); - for (XMLObject el : attr.getAttributeValues()) - attrList.add(el.getDOM().getTextContent()); - - attributs.put(attr.getName(), attrList); - - } - } - } - } + + private static final Logger log = LoggerFactory.getLogger(AssertionAttributeExtractor.class); + + private Assertion assertion = null; + private final Map<String, List<String>> attributs = new HashMap<>(); + // private PersonalAttributeList storkAttributes = new PersonalAttributeList(); + + private final List<String> minimalMdsAttributeNamesList = + Arrays.asList(PvpConstants.PRINCIPAL_NAME_NAME, PvpConstants.GIVEN_NAME_NAME, + PvpConstants.BIRTHDATE_NAME, PvpConstants.BPK_NAME); + + private final List<String> minimalIdlAttributeNamesList = + Arrays.asList(PvpConstants.EID_IDENTITY_LINK_NAME, PvpConstants.EID_SOURCE_PIN_NAME, + PvpConstants.EID_SOURCE_PIN_TYPE_NAME); + + /** + * Parse the SAML2 Response element and extracts included information. <br> + * <br> + * <b>INFO:</b> Actually, only the first SAML2 Assertion of the SAML2 Response is used! + * + * @param samlResponse SAML2 Response + * @throws AssertionAttributeExtractorExeption In case of an error + */ + public AssertionAttributeExtractor(final StatusResponseType samlResponse) + throws AssertionAttributeExtractorExeption { + if (samlResponse != null && samlResponse instanceof Response) { + final List<Assertion> assertions = ((Response) samlResponse).getAssertions(); + if (assertions.size() == 0) { + throw new AssertionAttributeExtractorExeption("Assertion"); + } else if (assertions.size() > 1) { + log.warn("Found more then ONE PVP2.1 assertions. Only the First is used."); + } + + assertion = assertions.get(0); + internalInitialize(); + + } else { + throw new AssertionAttributeExtractorExeption(); + } + } + + /** + * Parse the SAML2 Assertion element and extracts included information. <br> + * <br> + * + * @param assertion SAML2 Assertion + * @throws AssertionAttributeExtractorExeption In case of an error + */ + public AssertionAttributeExtractor(final Assertion assertion) + throws AssertionAttributeExtractorExeption { + this.assertion = assertion; + internalInitialize(); + + } + + /** + * Get all SAML2 attributes from first SAML2 AttributeStatement element. + * + * @return List of SAML2 Attributes + */ + public List<Attribute> getAllResponseAttributesFromFirstAttributeStatement() { + return assertion.getAttributeStatements().get(0).getAttributes(); + + } + + /** + * Get all SAML2 attributes of specific SAML2 AttributeStatement element. + * + * @param attrStatementID List ID of the AttributeStatement element + * @return List of SAML2 Attributes + */ + public List<Attribute> getAllResponseAttributes(final int attrStatementID) { + return assertion.getAttributeStatements().get(attrStatementID).getAttributes(); + + } + + /** + * check attributes from assertion with minimal required attribute list. + * + * @return + */ + public boolean containsAllRequiredAttributes() { + return containsAllRequiredAttributes(minimalMdsAttributeNamesList) + || containsAllRequiredAttributes(minimalIdlAttributeNamesList); + + } + + /** + * check attributes from assertion with attributeNameList bPK or enc_bPK are always needed. + * + * @param attributeNameList List of attributes which are required + * + * @return + */ + public boolean containsAllRequiredAttributes(final Collection<String> attributeNameList) { + + // first check if a bPK or an encrypted bPK is available + boolean flag = true; + for (final String attr : attributeNameList) { + if (!attributs.containsKey(attr)) { + flag = false; + log.debug("Assertion contains no Attribute " + attr); + + } + + } + + if (flag) { + return flag; + } else { + log.debug( + "Assertion contains no all minimum attributes from: " + attributeNameList.toString()); + return false; + + } + } + + public boolean containsAttribute(final String attributeName) { + return attributs.containsKey(attributeName); + + } + + /** + * Get single attribute with name. + * + * @param attributeName attribute Name + * @return Attribute value + */ + public String getSingleAttributeValue(final String attributeName) { + if (attributs.containsKey(attributeName) && attributs.get(attributeName).size() > 0) { + return attributs.get(attributeName).get(0); + } else { + return null; + } + + } + + public List<String> getAttributeValues(final String attributeName) { + return attributs.get(attributeName); + + } + + /** + * Return all include PVP attribute names. + * + * @return + */ + public Set<String> getAllIncludeAttributeNames() { + return attributs.keySet(); + + } + + /** + * Get User's nameId. + * + * @return nameId + * @throws AssertionAttributeExtractorExeption In case of an error + */ + public String getNameID() throws AssertionAttributeExtractorExeption { + if (assertion.getSubject() != null) { + final Subject subject = assertion.getSubject(); + + if (subject.getNameID() != null) { + if (StringUtils.isNotEmpty(subject.getNameID().getValue())) { + return subject.getNameID().getValue(); + } else { + log.error("SAML2 NameID Element is empty."); + } + } + } + + throw new AssertionAttributeExtractorExeption("nameID"); + } + + /** + * Get the Id attribute from SAML2 assertion. + * + * @return + */ + public String getAssertionID() { + return assertion.getID(); + + } + + /** + * Get SessionIndex from assertion. + * + * @return sessionIndex + * @throws AssertionAttributeExtractorExeption In case of an error + */ + public String getSessionIndex() throws AssertionAttributeExtractorExeption { + final AuthnStatement authn = getAuthnStatement(); + + if (StringUtils.isNotEmpty(authn.getSessionIndex())) { + return authn.getSessionIndex(); + } else { + throw new AssertionAttributeExtractorExeption("SessionIndex"); + } + } + + /** + * Get LoA from Assertion. + * + * @return LoA + * @throws AssertionAttributeExtractorExeption In case of an error + */ + public String getQaaLevel() throws AssertionAttributeExtractorExeption { + final AuthnStatement authn = getAuthnStatement(); + if (authn.getAuthnContext() != null + && authn.getAuthnContext().getAuthnContextClassRef() != null) { + final AuthnContextClassRef qaaClass = authn.getAuthnContext().getAuthnContextClassRef(); + + if (StringUtils.isNotEmpty(qaaClass.getAuthnContextClassRef())) { + return qaaClass.getAuthnContextClassRef(); + } else { + throw new AssertionAttributeExtractorExeption("AuthnContextClassRef (QAALevel)"); + } + } + + throw new AssertionAttributeExtractorExeption("AuthnContextClassRef"); + } + + public Assertion getFullAssertion() { + return assertion; + } + + + /** + * Get the Assertion validTo period. + * + *<p> + * Primarily, the 'SessionNotOnOrAfter' attribute in the SAML2 'AuthnStatment' element is used. If + * this is empty, this method returns value of SAML 'Conditions' element. + *</p> + * + * @return Date, until this SAML2 assertion is valid + */ + public Date getAssertionNotOnOrAfter() { + if (getFullAssertion().getAuthnStatements() != null + && getFullAssertion().getAuthnStatements().size() > 0) { + for (final AuthnStatement el : getFullAssertion().getAuthnStatements()) { + if (el.getSessionNotOnOrAfter() != null) { + return (el.getSessionNotOnOrAfter().toDate()); + } + } + + } + + return getFullAssertion().getConditions().getNotOnOrAfter().toDate(); + + } + + /** + * Get the Assertion validFrom period. + * + *<p> + * This method returns value of SAML 'Conditions' element. + *</p> + * + * @return Date, after this SAML2 assertion is valid, otherwise null + */ + public Date getAssertionNotBefore() { + try { + return getFullAssertion().getConditions().getNotBefore().toDate(); + + } catch (final NullPointerException e) { + return null; + + } + + } + + private AuthnStatement getAuthnStatement() throws AssertionAttributeExtractorExeption { + final List<AuthnStatement> authnList = assertion.getAuthnStatements(); + if (authnList.size() == 0) { + throw new AssertionAttributeExtractorExeption("AuthnStatement"); + } else if (authnList.size() > 1) { + log.warn("Found more then ONE AuthnStatements in PVP2.1 assertions. Only the First is used."); + } + + return authnList.get(0); + } + + private void internalInitialize() { + if (assertion.getAttributeStatements() != null + && assertion.getAttributeStatements().size() > 0) { + final AttributeStatement attrStat = assertion.getAttributeStatements().get(0); + for (final Attribute attr : attrStat.getAttributes()) { + if (attr.getName().startsWith(PvpConstants.STORK_ATTRIBUTE_PREFIX)) { + final List<String> storkAttrValues = new ArrayList<>(); + for (final XMLObject el : attr.getAttributeValues()) { + storkAttrValues.add(el.getDOM().getTextContent()); + } + + // PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(), + // false, storkAttrValues , "Available"); + // storkAttributes.put(attr.getName(), storkAttr ); + + } else { + final List<String> attrList = new ArrayList<>(); + for (final XMLObject el : attr.getAttributeValues()) { + attrList.add(el.getDOM().getTextContent()); + } + + attributs.put(attr.getName(), attrList); + + } + } + } + } } |