aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules')
-rw-r--r--id/server/modules/moa-id-module-openID/pom.xml86
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Configuration.java76
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Constants.java70
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20SessionObject.java74
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Util.java111
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java45
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java267
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAudiencesAttribute.java47
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java46
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java50
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java48
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java46
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdNonceAttribute.java57
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java46
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java46
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java46
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java46
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20AccessDeniedException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20CertificateErrorException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20Exception.java71
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidClientException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidGrantException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidRequestException.java35
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20OANotSupportedException.java44
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ResponseTypeException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ServerErrorException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20UnauthorizedClientException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20WrongParameterException.java34
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java121
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java84
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java116
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java49
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java63
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java29
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java213
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java234
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java144
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java215
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java124
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java157
-rw-r--r--id/server/modules/moa-id-module-openID/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo1
-rw-r--r--id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java131
-rw-r--r--id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20ErrorsTests.java184
-rw-r--r--id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20GoogleClientTestCase.java158
-rw-r--r--id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20UtilTest.java70
-rw-r--r--id/server/modules/moa-id-modules-saml1/pom.xml22
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java458
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java142
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java213
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java177
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java592
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java226
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java96
-rw-r--r--id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo1
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java367
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java101
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java531
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java249
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/CorporateBodyMandateContainer.java115
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java100
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java53
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java248
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKRequest.java254
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKResponse.java296
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java182
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java602
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java132
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/S2Constants.java66
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKPVPUtilits.java49
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java233
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/SimpleNamespaceContext.java83
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java29
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/AttributeProvider.java139
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/EHvdAttributeProviderPlugin.java254
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java231
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/PVPAuthenticationProvider.java238
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/SignedDocAttributeRequestProvider.java688
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/StorkAttributeRequestProvider.java193
-rw-r--r--id/server/modules/module-stork/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo1
-rw-r--r--id/server/modules/pom.xml2
80 files changed, 11085 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-module-openID/pom.xml b/id/server/modules/moa-id-module-openID/pom.xml
new file mode 100644
index 000000000..2a953bcab
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/pom.xml
@@ -0,0 +1,86 @@
+<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>MOA.id.server.modules</groupId>
+ <artifactId>moa-id-modules</artifactId>
+ <version>${moa-id-version}</version>
+ </parent>
+
+ <groupId>MOA.id.server.modules</groupId>
+ <artifactId>moa-id-module-openID</artifactId>
+ <version>${moa-id-version}</version>
+ <packaging>jar</packaging>
+
+ <name>MOA ID-Module OpenID Connect</name>
+
+ <properties>
+ <repositoryPath>${basedir}/../../../../repository</repositoryPath>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.http-client</groupId>
+ <artifactId>google-http-client-jackson2</artifactId>
+ <version>1.19.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.oauth-client</groupId>
+ <artifactId>google-oauth-client-jetty</artifactId>
+ <version>1.19.0</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>com.googlecode.jsontoken</groupId>
+ <artifactId>jsontoken</artifactId>
+ <version>1.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>google-collections</artifactId>
+ <groupId>com.google.collections</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>18.0</version>
+ </dependency>
+
+ <!-- TestNG -->
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>6.1.1</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Configuration.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Configuration.java
new file mode 100644
index 000000000..e2ac97535
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Configuration.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20;
+
+import java.util.Properties;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.util.FileUtils;
+
+public class OAuth20Configuration {
+
+ private static OAuth20Configuration instance;
+
+ public static OAuth20Configuration getInstance() {
+ if (instance == null) {
+ instance = new OAuth20Configuration();
+ }
+ return instance;
+ }
+
+ public static final String JWT_KEYSTORE = "jwt.ks.file";
+ public static final String JWT_KEYSTORE_PASSWORD = "jwt.ks.password";
+ public static final String JWT_KEY_NAME = "jwt.ks.key.name";
+ public static final String JWT_KEY_PASSWORD = "jwt.ks.key.password";
+
+ private Properties props;
+ private String rootDir = null;
+
+ private OAuth20Configuration() {
+ try {
+ props = AuthConfigurationProviderFactory.getInstance().getGeneralOAuth20ProperiesConfig();
+ rootDir = AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir();
+ }
+ catch (ConfigurationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getJWTKeyStore() {
+ return FileUtils.makeAbsoluteURL(props.getProperty(JWT_KEYSTORE), rootDir);
+ }
+
+ public String getJWTKeyStorePassword() {
+ return props.getProperty(JWT_KEYSTORE_PASSWORD).trim();
+ }
+
+ public String getJWTKeyName() {
+ return props.getProperty(JWT_KEY_NAME).trim();
+ }
+
+ public String getJWTKeyPassword() {
+ return props.getProperty(JWT_KEY_PASSWORD).trim();
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Constants.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Constants.java
new file mode 100644
index 000000000..b0736ff2e
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Constants.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20;
+
+public final class OAuth20Constants {
+
+ private OAuth20Constants() {
+ throw new InstantiationError();
+ }
+
+ public static final String ERRORPAGE = "moa_errorcodes.html";
+
+ // error parameters and error codes
+ public static final String PARAM_ERROR = "error";
+ public static final String PARAM_ERROR_DESCRIPTION = "error_description";
+ public static final String PARAM_ERROR_URI = "error_uri";
+
+ public static final String ERROR_INVALID_REQUEST = "invalid_request";
+ public static final String ERROR_UNSUPPORTED_RESPONSE_TYPE = "unsupported_response_type";
+ public static final String ERROR_INVALID_CLIENT = "invalid_client";
+ public static final String ERROR_ACCESS_DENIED = "access_denied";
+ public static final String ERROR_SERVER_ERROR = "server_error";
+ public static final String ERROR_INVALID_GRANT = "invalid_grant";
+ public static final String ERROR_UNAUTHORIZED_CLIENT = "unauthorized_client";
+
+ // request parameters
+ //public static final String PARAM_OA_URL = "oaURL";
+ public static final String PARAM_RESPONSE_TYPE = "response_type";
+ public static final String PARAM_REDIRECT_URI = "redirect_uri";
+ public static final String PARAM_STATE = "state";
+ public static final String PARAM_NONCE = "nonce";
+ public static final String PARAM_GRANT_TYPE = "grant_type";
+ public static final String PARAM_GRANT_TYPE_VALUE_AUTHORIZATION_CODE = "authorization_code";
+ public static final String PARAM_CLIENT_ID = "client_id";
+ public static final String PARAM_CLIENT_SECRET = "client_secret";
+ public static final String PARAM_SCOPE = "scope";
+ public static final String PARAM_MOA_MOD = "mod";
+ public static final String PARAM_MOA_ACTION = "action";
+
+
+ // reponse parameters
+ public static final String RESPONSE_CODE = "code";
+ public static final String RESPONSE_TOKEN = "token";
+ public static final String RESPONSE_ACCESS_TOKEN = "access_token";
+ public static final String RESPONSE_ID_TOKEN = "id_token";
+ public static final String RESPONSE_EXPIRES_IN = "expires_in";
+ public static final String RESPONSE_TOKEN_TYPE = "token_type";
+ public static final String RESPONSE_TOKEN_TYPE_VALUE_BEARER = "Bearer";
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20SessionObject.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20SessionObject.java
new file mode 100644
index 000000000..4a33a44b7
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20SessionObject.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+
+public class OAuth20SessionObject implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private String scope;
+
+ private String code;
+
+ private Map<String, Object> authDataSession;
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ /**
+ * @return the code
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
+ * @param code
+ * the code to set
+ */
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public Map<String, Object> getAuthDataSession() {
+ return authDataSession;
+ }
+
+ public void setAuthDataSession(Map<String, Object> idToken) {
+ this.authDataSession = idToken;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Util.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Util.java
new file mode 100644
index 000000000..912060949
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Util.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.google.gson.JsonObject;
+
+public final class OAuth20Util {
+
+ public static final String REGEX_HTTPS = "^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
+ public static final String REGEX_FILE = "^(file):/.[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
+
+ private OAuth20Util() {
+ throw new InstantiationError();
+ }
+
+ /**
+ * Simple helper function to add parameter to a url
+ *
+ * @param url
+ * @param name
+ * @param value
+ * @throws UnsupportedEncodingException
+ */
+ public static void addParameterToURL(final StringBuilder url, final String name, final String value)
+ throws UnsupportedEncodingException {
+ if (url.indexOf("?") < 0) {
+ url.append("?");
+ } else {
+ url.append("&");
+ }
+ // URLEncoder.encode(value, "UTF-8")
+ url.append(name).append("=").append(value);
+ }
+
+ public static boolean isUrl(final String url) {
+ Pattern urlPattern;
+ if (url.startsWith("file")) {
+ urlPattern = Pattern.compile(REGEX_FILE, Pattern.CASE_INSENSITIVE);
+ } else {
+ urlPattern = Pattern.compile(REGEX_HTTPS, Pattern.CASE_INSENSITIVE);
+ }
+
+ Matcher matcher = urlPattern.matcher(url);
+ return matcher.find();
+ }
+
+ public static boolean isValidStateValue(String state) {
+ Pattern urlPattern = Pattern.compile("javascript|<|>|&|;", Pattern.CASE_INSENSITIVE);
+ Matcher matcher = urlPattern.matcher(state);
+ return !matcher.find();
+ }
+
+ public static void addProperytiesToJsonObject(JsonObject jsonObject, Map<String, Object> params) {
+ for (Map.Entry<String, Object> param : params.entrySet()) {
+
+ if (!StringUtils.isEmpty(param.getKey()) && param.getValue() != null) {
+
+ // check for integer
+ try {
+ int i = Integer.parseInt(String.valueOf(param.getValue()));
+ jsonObject.addProperty(param.getKey(), i);
+ continue;
+ }
+ catch (NumberFormatException e) {
+ }
+
+ // check for long
+ try {
+ long l = Long.parseLong(String.valueOf(param.getValue()));
+ jsonObject.addProperty(param.getKey(), l);
+ continue;
+ }
+ catch (NumberFormatException e) {
+ }
+
+ // string
+ if (param.getValue() instanceof String) {
+ jsonObject.addProperty(param.getKey(), String.valueOf(param.getValue()));
+ }
+ }
+ }
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java
new file mode 100644
index 000000000..eb3cfcccb
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20;
+
+public class Pair<P1, P2> {
+ private final P1 first;
+ private final P2 second;
+
+ private Pair(final P1 newFirst, final P2 newSecond) {
+ this.first = newFirst;
+ this.second = newSecond;
+ }
+
+ public P1 getFirst() {
+ return this.first;
+ }
+
+ public P2 getSecond() {
+ return this.second;
+ }
+
+ public static <P1, P2> Pair<P1, P2> newInstance(final P1 newFirst, final P2 newSecond) {
+ return new Pair<P1, P2>(newFirst, newSecond);
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java
new file mode 100644
index 000000000..439d08e0b
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.oauth20.Pair;
+import at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20AuthRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.BPKAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDAuthBlock;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDCcsURL;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDCitizenQAALevelAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDIdentityLinkBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDIssuingNationAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSTORKTOKEN;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSectorForIDAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSignerCertificate;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSourcePIN;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSourcePINType;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateLegalPersonFullNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateLegalPersonSourcePinAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateLegalPersonSourcePinTypeAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonBPKAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonBirthDateAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonFamilyNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonGivenNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonSourcePinAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonSourcePinTypeAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateProfRepDescAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateProfRepOIDAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateReferenceValueAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateTypeAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKAdoptedFamilyNameAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKAgeAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKCanonicalResidenceAddressAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKCountryCodeOfBirthAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKFiscalNumberAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKGenderAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKInhertedFamilyNameAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKIsAgeOverAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKMaritalStatusAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKNationalityCodeAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKPseudonymAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKResidencePermitAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKTextResidenceAddressAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.STORKTitleAttributBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+import at.gv.egovernment.moa.logging.Logger;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+public final class OAuth20AttributeBuilder {
+
+ private OAuth20AttributeBuilder() {
+ throw new InstantiationError();
+ }
+
+ private static IAttributeGenerator<Pair<String, JsonPrimitive>> generator = new IAttributeGenerator<Pair<String, JsonPrimitive>>() {
+
+ public Pair<String, JsonPrimitive> buildStringAttribute(final String friendlyName, final String name, final String value) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(value));
+ }
+
+ public Pair<String, JsonPrimitive> buildIntegerAttribute(final String friendlyName, final String name, final int value) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(value));
+ }
+
+ public Pair<String, JsonPrimitive> buildLongAttribute(final String friendlyName, final String name, final long value) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(value));
+ }
+
+ public Pair<String, JsonPrimitive> buildEmptyAttribute(final String friendlyName, final String name) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(""));
+ }
+
+ };
+
+ private static final List<IAttributeBuilder> buildersOpenId = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersProfile = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersEID = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersEIDGov = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersMandate = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersSTORK = new ArrayList<IAttributeBuilder>();
+ static {
+ // openId
+ buildersOpenId.add(new OpenIdIssuerAttribute());
+ buildersOpenId.add(new OpenIdSubjectIdentifierAttribute());
+ buildersOpenId.add(new OpenIdExpirationTimeAttribute());
+ buildersOpenId.add(new OpenIdIssueInstantAttribute());
+ buildersOpenId.add(new OpenIdAuthenticationTimeAttribute());
+ buildersOpenId.add(new OpenIdAudiencesAttribute());
+ buildersOpenId.add(new OpenIdNonceAttribute());
+
+ // profile
+ buildersProfile.add(new ProfileGivenNameAttribute());
+ buildersProfile.add(new ProfileFamilyNameAttribute());
+ buildersProfile.add(new ProfileDateOfBirthAttribute());
+
+ // EID
+ buildersEID.add(new EIDCcsURL());
+ buildersEID.add(new EIDCitizenQAALevelAttributeBuilder());
+ buildersEID.add(new EIDIssuingNationAttributeBuilder());
+ buildersEID.add(new EIDSectorForIDAttributeBuilder());
+ buildersEID.add(new EIDAuthBlock());
+ buildersEID.add(new EIDSignerCertificate());
+ buildersEID.add(new BPKAttributeBuilder());
+
+ // eID_gov
+ buildersEIDGov.add(new EIDSourcePIN());
+ buildersEIDGov.add(new EIDSourcePINType());
+ buildersEIDGov.add(new EIDIdentityLinkBuilder());
+
+ // mandate
+ buildersMandate.add(new MandateTypeAttributeBuilder());
+ buildersMandate.add(new MandateReferenceValueAttributeBuilder());
+
+ buildersMandate.add(new MandateNaturalPersonSourcePinAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonSourcePinTypeAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonBPKAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonFamilyNameAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonGivenNameAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonBirthDateAttributeBuilder());
+
+ buildersMandate.add(new MandateLegalPersonSourcePinAttributeBuilder());
+ buildersMandate.add(new MandateLegalPersonSourcePinTypeAttributeBuilder());
+ buildersMandate.add(new MandateLegalPersonFullNameAttributeBuilder());
+
+ buildersMandate.add(new MandateProfRepOIDAttributeBuilder());
+ buildersMandate.add(new MandateProfRepDescAttributeBuilder());
+
+ // STORK
+ buildersSTORK.add(new EIDSTORKTOKEN());
+ buildersSTORK.add(new STORKAdoptedFamilyNameAttributBuilder());
+ buildersSTORK.add(new STORKAgeAttributBuilder());
+ buildersSTORK.add(new STORKCanonicalResidenceAddressAttributBuilder());
+ buildersSTORK.add(new STORKCountryCodeOfBirthAttributBuilder());
+ buildersSTORK.add(new STORKFiscalNumberAttributBuilder());
+ buildersSTORK.add(new STORKGenderAttributBuilder());
+ buildersSTORK.add(new STORKInhertedFamilyNameAttributBuilder());
+ buildersSTORK.add(new STORKIsAgeOverAttributBuilder());
+ buildersSTORK.add(new STORKMaritalStatusAttributBuilder());
+ buildersSTORK.add(new STORKNationalityCodeAttributBuilder());
+ buildersSTORK.add(new STORKPseudonymAttributBuilder());
+ buildersSTORK.add(new STORKResidencePermitAttributBuilder());
+ buildersSTORK.add(new STORKTextResidenceAddressAttributBuilder());
+ buildersSTORK.add(new STORKTitleAttributBuilder());
+ }
+
+ private static void addAttibutes(final List<IAttributeBuilder> builders, final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData, OAuth20AuthRequest oAuthRequest) {
+ for (IAttributeBuilder b : builders) {
+ try {
+ //TODO: better solution requires more refactoring :(
+ Pair<String, JsonPrimitive> attribute = null;
+ if (b instanceof OpenIdNonceAttribute) {
+ OpenIdNonceAttribute nonceBuilder = (OpenIdNonceAttribute) b;
+ attribute = nonceBuilder.build(oaParam, authData, oAuthRequest, generator);
+
+ } else
+ attribute = b.build(oaParam, authData, generator);
+
+ if (attribute != null && !StringUtils.isEmpty(attribute.getSecond().getAsString())) {
+ jsonObject.add(attribute.getFirst(), attribute.getSecond());
+ }
+ }
+ catch (AttributeException e) {
+ Logger.info("Cannot add attribute " + b.getName());
+ }
+ }
+ }
+
+ public static void addScopeOpenId(final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData,
+ final OAuth20AuthRequest oAuthRequest) {
+ addAttibutes(buildersOpenId, jsonObject, oaParam, authData, oAuthRequest);
+ }
+
+ public static void addScopeProfile(final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData) {
+ addAttibutes(buildersProfile, jsonObject, oaParam, authData, null);
+ }
+
+ public static void addScopeEID(final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData) {
+ addAttibutes(buildersEID, jsonObject, oaParam, authData, null);
+ }
+
+ public static void addScopeEIDGov(final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData) {
+ addAttibutes(buildersEIDGov, jsonObject, oaParam, authData, null);
+ }
+
+ public static void addScopeMandate(final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData) {
+ addAttibutes(buildersMandate, jsonObject, oaParam, authData, null);
+ }
+
+ public static void addScopeSTORK(final JsonObject jsonObject,
+ final OAAuthParameter oaParam, final IAuthData authData) {
+ addAttibutes(buildersSTORK, jsonObject, oaParam, authData, null);
+ }
+
+ /**
+ * @return the buildersprofile
+ */
+ public static List<IAttributeBuilder> getBuildersprofile() {
+ return buildersProfile;
+ }
+
+ /**
+ * @return the builderseid
+ */
+ public static List<IAttributeBuilder> getBuilderseid() {
+ return buildersEID;
+ }
+
+ /**
+ * @return the builderseidgov
+ */
+ public static List<IAttributeBuilder> getBuilderseidgov() {
+ return buildersEIDGov;
+ }
+
+ /**
+ * @return the buildersmandate
+ */
+ public static List<IAttributeBuilder> getBuildersmandate() {
+ return buildersMandate;
+ }
+
+ /**
+ * @return the buildersstork
+ */
+ public static List<IAttributeBuilder> getBuildersstork() {
+ return buildersSTORK;
+ }
+
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAudiencesAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAudiencesAttribute.java
new file mode 100644
index 000000000..404eb1b44
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAudiencesAttribute.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdAudiencesAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "aud";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", oaParam.getPublicURLPrefix());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
+
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java
new file mode 100644
index 000000000..121648499
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdAuthenticationTimeAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "auth_time";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildLongAttribute(this.getName(), "", ((long) (authData.getIssueInstant().getTime() / 1000)));
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java
new file mode 100644
index 000000000..9230c0105
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import java.util.Date;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdExpirationTimeAttribute implements IAttributeBuilder {
+
+ public static final int expirationTime = 5 * 60; // in seconds
+
+ public String getName() {
+ return "exp";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildLongAttribute(this.getName(), "", (long) (new Date().getTime() / 1000 + expirationTime));
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java
new file mode 100644
index 000000000..3bdda5c2a
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import java.util.Date;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdIssueInstantAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "iat";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildLongAttribute(this.getName(), "", (long) (new Date().getTime() / 1000));
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java
new file mode 100644
index 000000000..85c46d5b2
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdIssuerAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "iss";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getIssuer());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdNonceAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdNonceAttribute.java
new file mode 100644
index 000000000..6baa69b1e
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdNonceAttribute.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20AuthRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+public class OpenIdNonceAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "nonce";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", null);
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData, OAuth20AuthRequest oAuthRequest,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ if (MiscUtil.isNotEmpty(oAuthRequest.getNonce()))
+ return g.buildStringAttribute(this.getName(), "", oAuthRequest.getNonce());
+ else
+ return null;
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
+
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java
new file mode 100644
index 000000000..d5bda0dba
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdSubjectIdentifierAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "sub";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getBPK());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java
new file mode 100644
index 000000000..dd84536ed
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class ProfileDateOfBirthAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "birthdate";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getFormatedDateOfBirth());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java
new file mode 100644
index 000000000..02cc66e4b
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class ProfileFamilyNameAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "family_name";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getFamilyName());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java
new file mode 100644
index 000000000..302ce8105
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class ProfileGivenNameAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "given_name";
+ }
+
+ public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getGivenName());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20AccessDeniedException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20AccessDeniedException.java
new file mode 100644
index 000000000..25a30bfcf
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20AccessDeniedException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20AccessDeniedException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20AccessDeniedException() {
+ super(OAuth20Constants.ERROR_ACCESS_DENIED, "oauth20.05", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20CertificateErrorException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20CertificateErrorException.java
new file mode 100644
index 000000000..a938d1544
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20CertificateErrorException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20CertificateErrorException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20CertificateErrorException(final String name) {
+ super(OAuth20Constants.ERROR_SERVER_ERROR, "oauth20.09", new Object[] { name });
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20Exception.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20Exception.java
new file mode 100644
index 000000000..307615fbd
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20Exception.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
+
+public class OAuth20Exception extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ private String messageId;
+
+ private String errorCode;
+
+ public OAuth20Exception(final String errorCode, final String messageId, final Object[] parameters) {
+ super(MOAIDMessageProvider.getInstance().getMessage(messageId, parameters));
+ this.errorCode = errorCode;
+ this.messageId = messageId;
+ }
+
+ /**
+ * @return the messageId
+ */
+ public String getMessageId() {
+ return messageId;
+ }
+
+ /**
+ * @param messageId
+ * the messageId to set
+ */
+ public void setMessageId(String messageId) {
+ this.messageId = messageId;
+ }
+
+ /**
+ * @return the errorCode
+ */
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * @param errorCode
+ * the errorCode to set
+ */
+ public void setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidClientException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidClientException.java
new file mode 100644
index 000000000..9c2875cef
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidClientException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20InvalidClientException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20InvalidClientException() {
+ super(OAuth20Constants.ERROR_INVALID_CLIENT, "oauth20.05", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidGrantException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidGrantException.java
new file mode 100644
index 000000000..c0f03c735
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidGrantException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20InvalidGrantException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20InvalidGrantException() {
+ super(OAuth20Constants.ERROR_INVALID_GRANT, "oauth20.07", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidRequestException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidRequestException.java
new file mode 100644
index 000000000..b980840c2
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20InvalidRequestException.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20InvalidRequestException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20InvalidRequestException() {
+ super(OAuth20Constants.ERROR_INVALID_REQUEST, "oauth20.04", new Object[] {});
+
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20OANotSupportedException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20OANotSupportedException.java
new file mode 100644
index 000000000..0edeb89bc
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20OANotSupportedException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+/**
+ * @author tlenz
+ *
+ */
+public class OAuth20OANotSupportedException extends OAuth20Exception {
+
+ private static final long serialVersionUID = -8713091674236329339L;
+
+ /**
+ * @param errorCode
+ * @param messageId
+ * @param parameters
+ */
+ public OAuth20OANotSupportedException() {
+ super(OAuth20Constants.ERROR_SERVER_ERROR, "oauth20.06", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ResponseTypeException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ResponseTypeException.java
new file mode 100644
index 000000000..8de854821
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ResponseTypeException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20ResponseTypeException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20ResponseTypeException() {
+ super(OAuth20Constants.ERROR_UNSUPPORTED_RESPONSE_TYPE, "oauth20.03", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ServerErrorException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ServerErrorException.java
new file mode 100644
index 000000000..470507f08
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20ServerErrorException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20ServerErrorException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20ServerErrorException() {
+ super(OAuth20Constants.ERROR_SERVER_ERROR, "oauth20.10", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20UnauthorizedClientException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20UnauthorizedClientException.java
new file mode 100644
index 000000000..ee7b4d7d6
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20UnauthorizedClientException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20UnauthorizedClientException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20UnauthorizedClientException() {
+ super(OAuth20Constants.ERROR_UNAUTHORIZED_CLIENT, "oauth20.08", new Object[] {});
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20WrongParameterException.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20WrongParameterException.java
new file mode 100644
index 000000000..48267d88c
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/exceptions/OAuth20WrongParameterException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.exceptions;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+
+public class OAuth20WrongParameterException extends OAuth20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OAuth20WrongParameterException(final String name) {
+ super(OAuth20Constants.ERROR_INVALID_REQUEST, "oauth20.02", new Object[] { name });
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java
new file mode 100644
index 000000000..50e57bdc1
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.
+ ******************************************************************************/
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ */
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+
+import net.oauth.jsontoken.crypto.AbstractSigner;
+import net.oauth.jsontoken.crypto.RsaSHA256Signer;
+import net.oauth.jsontoken.crypto.SignatureAlgorithm;
+
+/**
+ * Signer that can sign byte arrays using a {@link PrivateKey} and SHA-256. <br/>
+ * This is something like a copy of the {@link RsaSHA256Signer}.
+ *
+ */
+public class OAuth20SHA256Signer extends AbstractSigner implements OAuthSigner {
+
+ private final Signature signature;
+ private final PrivateKey signingKey;
+ private final OAuthSignatureAlgorithm algorithm;
+
+ /**
+ * Public constructor.
+ *
+ * @param issuer
+ * The id of this signer, to be included in the JSON Token's envelope.
+ * @param keyId
+ * The id of the key used by this signer, to be included in the JSON Token's
+ * envelope.
+ * @param key
+ * the private key to be used for signing.
+ * @throws InvalidKeyException
+ * if the key is unsuitable for RSA signing.
+ */
+ public OAuth20SHA256Signer(final String issuer, final String keyId, final PrivateKey key) throws InvalidKeyException {
+ super(issuer, keyId);
+
+ this.signingKey = key;
+ this.algorithm = OAuth20SignatureUtil.findSignature(key);
+
+ try {
+ this.signature = this.algorithm.getSignatureInstance();
+ this.signature.initSign(signingKey);
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ catch (NoSuchProviderException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see net.oauth.jsontoken.crypto.Signer#getSignatureAlgorithm()
+ */
+ public SignatureAlgorithm getSignatureAlgorithm() {
+ // it is fine to return RS256 because we overwrite the JsonToken for the algorithm name. But
+ // we need the internal SHA256 which is used.
+ return SignatureAlgorithm.RS256;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see net.oauth.jsontoken.crypto.Signer#sign(byte[])
+ */
+ public byte[] sign(byte[] source) throws SignatureException {
+ try {
+ signature.initSign(signingKey);
+ }
+ catch (InvalidKeyException e) {
+ throw new RuntimeException("key somehow became invalid since calling the constructor");
+ }
+ signature.update(source);
+ return signature.sign();
+ }
+
+ public OAuthSignatureAlgorithm getOAuthSignatureAlgorithm() {
+ return this.algorithm;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java
new file mode 100644
index 000000000..374320a5a
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+
+import net.oauth.jsontoken.crypto.RsaSHA256Verifier;
+import net.oauth.jsontoken.crypto.Verifier;
+
+/**
+ * A verifier that can verify signatures on byte arrays using a {@link PublicKey} and SHA-256. <br/>
+ * This is something like a copy of the {@link RsaSHA256Verifier}.
+ */
+public class OAuth20SHA256Verifier implements Verifier {
+
+ private final PublicKey verificationKey;
+ private final Signature signer;
+
+ /**
+ * Public Constructor.
+ *
+ * @param verificationKey
+ * the key used to verify the signature.
+ */
+ public OAuth20SHA256Verifier(final PublicKey verificationKey) {
+ this.verificationKey = verificationKey;
+
+ try {
+ this.signer = OAuth20SignatureUtil.findSignature(verificationKey).getSignatureInstance();
+ this.signer.initVerify(verificationKey);
+ }
+ catch (InvalidKeyException e) {
+ throw new IllegalStateException("key is invalid", e);
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ catch (NoSuchProviderException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see net.oauth.jsontoken.crypto.Verifier#verifySignature(byte[], byte[])
+ */
+ public void verifySignature(byte[] source, byte[] signature) throws SignatureException {
+ try {
+ signer.initVerify(verificationKey);
+ }
+ catch (InvalidKeyException e) {
+ throw new RuntimeException("key someone become invalid since calling the constructor");
+ }
+ signer.update(source);
+ if (!signer.verify(signature)) {
+ throw new SignatureException("signature did not verify");
+ }
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java
new file mode 100644
index 000000000..9f20ee956
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import org.apache.commons.lang.StringUtils;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Configuration;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20CertificateErrorException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.KeyStoreUtils;
+
+public final class OAuth20SignatureUtil {
+
+ private OAuth20SignatureUtil() {
+ throw new InstantiationError();
+ }
+
+ static OAuthSignatureAlgorithm findSignature(final PrivateKey key) {
+ Logger.debug("OAuth - Looking for signature for key " + key.getClass());
+ if (key instanceof RSAPrivateKey) {
+ Logger.debug("OAuth - going to uses SHA256withRSA signature");
+ return OAuthSignatureAlgorithm.RS256;
+ } else if (key instanceof ECPrivateKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature");
+ return OAuthSignatureAlgorithm.ECDSA256;
+ } else if (key instanceof iaik.security.ecc.ecdsa.ECPrivateKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature with iaik");
+ return OAuthSignatureAlgorithm.ECDSA256_IAKIK;
+ } else {
+ throw new IllegalStateException("Cannot find an alorithm for the given private key");
+ }
+ }
+
+ static OAuthSignatureAlgorithm findSignature(final PublicKey key) {
+ if (key instanceof RSAPublicKey) {
+ Logger.debug("OAuth - going to uses SHA256withRSA signature");
+ return OAuthSignatureAlgorithm.RS256;
+ } else if (key instanceof ECPublicKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature");
+ return OAuthSignatureAlgorithm.ECDSA256;
+ } else if (key instanceof iaik.security.ecc.ecdsa.ECPublicKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature with iaik");
+ return OAuthSignatureAlgorithm.ECDSA256_IAKIK;
+ } else {
+ throw new IllegalStateException("Cannot find an alorithm for the given private key");
+ }
+ }
+
+ public static OAuthSigner loadSigner(String issuer) throws OAuth20Exception {
+ OAuth20Configuration globalConfig = OAuth20Configuration.getInstance();
+
+ if (StringUtils.isEmpty(globalConfig.getJWTKeyStore())) {
+ throw new OAuth20CertificateErrorException("keystore");
+ }
+
+ if (StringUtils.isEmpty(globalConfig.getJWTKeyName())) {
+ throw new OAuth20CertificateErrorException("key name");
+ }
+
+ try {
+ KeyStore ks = KeyStoreUtils.loadKeyStore(globalConfig.getJWTKeyStore(), globalConfig.getJWTKeyStorePassword());
+
+ X509Certificate certificate = (X509Certificate) ks.getCertificate(globalConfig.getJWTKeyName());
+
+ PrivateKey privateKey = (PrivateKey) ks.getKey(globalConfig.getJWTKeyName(), globalConfig.getJWTKeyPassword()
+ .toCharArray());
+ BasicX509Credential credential = new BasicX509Credential();
+ credential.setEntityCertificate(certificate);
+ credential.setPrivateKey(privateKey);
+
+ // Logger.debug("Going to use X509Certificate:");
+ // Logger.debug(certificate);
+ // Logger.debug("Going to use private key:");
+ // Logger.debug(privateKey);
+
+ return new OAuth20SHA256Signer(issuer, globalConfig.getJWTKeyName(), credential.getPrivateKey());
+
+ }
+ catch (Exception e) {
+ Logger.error(e.getMessage(), e);
+ throw new OAuth20CertificateErrorException("keystore");
+ }
+
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java
new file mode 100644
index 000000000..af17825fd
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.json;
+
+import net.oauth.jsontoken.JsonToken;
+
+import com.google.gson.JsonObject;
+
+public class OAuthJsonToken extends JsonToken {
+
+ private final OAuthSigner signer;
+
+ public OAuthJsonToken(OAuthSigner signer) {
+ super(signer);
+ this.signer = signer;
+ }
+
+ @Override
+ public JsonObject getHeader() {
+ JsonObject header = new JsonObject();
+ header.addProperty(ALGORITHM_HEADER, signer.getOAuthSignatureAlgorithm().getAlgorithm());
+ String keyId = getKeyId();
+ if (keyId != null) {
+ header.addProperty(KEY_ID_HEADER, keyId);
+ }
+ return header;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java
new file mode 100644
index 000000000..db15516e7
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java
@@ -0,0 +1,63 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Enum of the signature algorithms supported by this package.
+ */
+public enum OAuthSignatureAlgorithm {
+ ECDSA256("SHA256withECDSA", "ECDSA256", null), RS256("SHA256withRSA", "RS256", null), ECDSA256_IAKIK("SHA1withECDSA", "ECDSA256",
+ "IAIK_ECC");
+
+ private final String signatureName;
+ private final String algorithm;
+ private final String providerName;
+
+ private OAuthSignatureAlgorithm(final String signatureName, final String hashAlg, final String providerName) {
+ this.signatureName = signatureName;
+ this.algorithm = hashAlg;
+ this.providerName = providerName;
+ }
+
+ /**
+ * What the signature algorithm is named in the "alg" parameter in a JSON Token's envelope.
+ */
+ public String getAlgorithm() {
+ return this.algorithm;
+ }
+
+ /**
+ *
+ * @return the signature name like SHA256withECDSA or SHA256withRSA
+ */
+ public String getSignatureName() {
+ return this.signatureName;
+ }
+
+ /**
+ * Calls {@link Signature#getInstance(String)} with the defined signature name
+ *
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws NoSuchProviderException
+ */
+ public Signature getSignatureInstance() throws NoSuchAlgorithmException, NoSuchProviderException {
+ if (!StringUtils.isEmpty(this.providerName)) {
+ //return Signature.getInstance(this.signatureName, this.providerName);
+ return Signature.getInstance(this.signatureName, this.providerName);
+ } else {
+ return Signature.getInstance(this.signatureName);
+ }
+ }
+
+ /**
+ * Given the name of the algorithm in the envelope, returns the corresponding enum instance.
+ */
+ public static OAuthSignatureAlgorithm getFromJsonName(String name) {
+ return OAuthSignatureAlgorithm.valueOf(name);
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java
new file mode 100644
index 000000000..3904f8cef
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.json;
+
+import net.oauth.jsontoken.crypto.Signer;
+
+public interface OAuthSigner extends Signer {
+ public abstract OAuthSignatureAlgorithm getOAuthSignatureAlgorithm();
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java
new file mode 100644
index 000000000..d90df51e7
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.protocol;
+
+import java.security.SignatureException;
+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.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationImpl;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20SessionObject;
+import at.gv.egovernment.moa.id.protocols.oauth20.Pair;
+import at.gv.egovernment.moa.id.protocols.oauth20.attributes.OAuth20AttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.oauth20.attributes.OpenIdExpirationTimeAttribute;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ResponseTypeException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ServerErrorException;
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuth20SignatureUtil;
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuthJsonToken;
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuthSigner;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+class OAuth20AuthAction implements IAction {
+
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp,
+ IAuthData authData) throws MOAIDException {
+
+ OAuth20AuthRequest oAuthRequest = (OAuth20AuthRequest) req;
+ String responseType = oAuthRequest.getResponseType();
+
+ MOAReversionLogger.getInstance().logEvent(req, MOAIDEventConstants.AUTHPROTOCOL_OPENIDCONNECT_AUTHREQUEST);
+
+ String code = Random.nextRandom();
+
+ try {
+
+ String accessToken = UUID.randomUUID().toString();
+
+ Logger.debug("Stored session with id: " + code);
+ OAuth20SessionObject o = new OAuth20SessionObject();
+ if (responseType.equals(OAuth20Constants.RESPONSE_CODE)) {
+ o.setScope(oAuthRequest.getScope());
+ o.setCode(code);
+
+ //generate idToken from MOASession
+ Map<String, Object> idToken = generateIDToken(o, oAuthRequest, authData, accessToken);
+ o.setAuthDataSession(idToken);
+
+ } else if (responseType.equals(OAuth20Constants.RESPONSE_TOKEN)) {
+ throw new OAuth20ResponseTypeException();
+ }
+
+ // store data in oath session
+ AssertionStorage.getInstance().put(code, o);
+
+ Logger.debug("Saved OAuth20SessionObject in session with id: " + code);
+
+ // add code and state to redirect url
+ httpResp.setStatus(HttpServletResponse.SC_FOUND);
+ String redirectURI = oAuthRequest.getRedirectUri();
+ String state = oAuthRequest.getState();
+
+ redirectURI = this.addURLParameter(redirectURI, OAuth20Constants.RESPONSE_CODE, code);
+ redirectURI = this.addURLParameter(redirectURI, OAuth20Constants.PARAM_STATE, state);
+
+ String finalUrl = redirectURI;
+ httpResp.addHeader("Location", finalUrl);
+ Logger.debug("REDIRECT TO: " + finalUrl.toString());
+
+
+ //TODO: maybe add bPK / wbPK to SLO information
+ SLOInformationInterface sloInformation = new SLOInformationImpl(accessToken, null, null, req.requestedModule());
+
+ return sloInformation;
+ }
+ catch (Exception e) {
+
+ //remove OAuthSessionObject if it already exists
+ if (AssertionStorage.getInstance().containsKey(code)) {
+ AssertionStorage.getInstance().remove(code);
+ }
+
+ if (e instanceof OAuth20Exception) {
+ throw (OAuth20Exception) e;
+ }
+ throw new OAuth20ServerErrorException();
+ }
+
+ }
+
+ private Map<String, Object> generateIDToken(OAuth20SessionObject auth20SessionObject,
+ OAuth20AuthRequest oAuthRequest, IAuthData authData, String accessToken) throws SignatureException, MOAIDException {
+
+ // create response
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(OAuth20Constants.RESPONSE_ACCESS_TOKEN, accessToken);
+ params.put(OAuth20Constants.RESPONSE_TOKEN_TYPE, OAuth20Constants.RESPONSE_TOKEN_TYPE_VALUE_BEARER);
+ params.put(OAuth20Constants.RESPONSE_EXPIRES_IN, OpenIdExpirationTimeAttribute.expirationTime);
+ // build id token and scope
+ Pair<String, String> pair = buildIdToken(auth20SessionObject.getScope(), oAuthRequest,
+ authData);
+ Logger.debug("RESPONSE ID_TOKEN: " + pair.getFirst());
+ params.put(OAuth20Constants.RESPONSE_ID_TOKEN, pair.getFirst());
+ Logger.debug("RESPONSE SCOPE: " + pair.getSecond());
+ params.put(OAuth20Constants.PARAM_SCOPE, pair.getSecond());
+
+ return params;
+
+ }
+
+ private Pair<String, String> buildIdToken(String scope, OAuth20AuthRequest oAuthRequest, IAuthData authData)
+ throws MOAIDException, SignatureException {
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(oAuthRequest.getOAURL());
+
+ OAuthSigner signer = OAuth20SignatureUtil.loadSigner(authData.getIssuer());
+ OAuthJsonToken token = new OAuthJsonToken(signer);
+
+ StringBuilder resultScopes = new StringBuilder();
+ // always fill with open id
+ OAuth20AttributeBuilder.addScopeOpenId(token.getPayloadAsJsonObject(), oaParam, authData, oAuthRequest);
+ resultScopes.append("openId");
+
+ for (String s : scope.split(" ")) {
+ if (s.equalsIgnoreCase("profile")) {
+ OAuth20AttributeBuilder.addScopeProfile(token.getPayloadAsJsonObject(), oaParam, authData);
+ resultScopes.append(" profile");
+ } else if (s.equalsIgnoreCase("eID")) {
+ OAuth20AttributeBuilder.addScopeEID(token.getPayloadAsJsonObject(), oaParam, authData);
+ resultScopes.append(" eID");
+ } else if (s.equalsIgnoreCase("eID_gov")) {
+ OAuth20AttributeBuilder.addScopeEIDGov(token.getPayloadAsJsonObject(), oaParam, authData);
+ resultScopes.append(" eID_gov");
+ } else if (s.equalsIgnoreCase("mandate")) {
+ OAuth20AttributeBuilder.addScopeMandate(token.getPayloadAsJsonObject(), oaParam, authData);
+ resultScopes.append(" mandate");
+ } else if (s.equalsIgnoreCase("stork")) {
+ OAuth20AttributeBuilder.addScopeSTORK(token.getPayloadAsJsonObject(), oaParam, authData);
+ resultScopes.append(" stork");
+ }
+ }
+
+ // add properties and sign
+ // HmacSHA256Signer signer = new HmacSHA256Signer("testSigner", "key_id",
+ // "super_secure_pwd".getBytes());
+ // Signer signer = OAuth20Util.loadSigner(authData.getIssuer(), oaParam.getoAuth20Config());
+
+ return Pair.newInstance(token.serializeAndSign(), resultScopes.toString());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls
+ * .IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ return true;
+ }
+
+ private String addURLParameter(String url, String name, String value) {
+ String param = name + "=" + value;
+ if (url.indexOf("?") < 0) {
+ return url + "?" + param;
+ } else {
+ return url + "&" + param;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ public String getDefaultActionName() {
+ return OAuth20Protocol.AUTH_ACTION;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java
new file mode 100644
index 000000000..06509b333
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.protocol;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.opensaml.saml2.core.Attribute;
+
+import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
+import at.gv.egovernment.moa.id.protocols.oauth20.attributes.OAuth20AttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20AccessDeniedException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ResponseTypeException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParameterException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.logging.Logger;
+
+public class OAuth20AuthRequest extends OAuth20BaseRequest {
+
+ private static final long serialVersionUID = 1L;
+
+ private String responseType;
+ private String state;
+ private String redirectUri;
+ private String scope;
+ private String clientID;
+ private String nonce;
+
+ /**
+ * @return the responseType
+ */
+ public String getResponseType() {
+ return responseType;
+ }
+
+ /**
+ * @param responseType
+ * the responseType to set
+ */
+ public void setResponseType(String responseType) {
+ this.responseType = responseType;
+ }
+
+ /**
+ * @return the state
+ */
+ public String getState() {
+ return state;
+ }
+
+ /**
+ * @param state
+ * the state to set
+ */
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ /**
+ * @return the redirectUri
+ */
+ public String getRedirectUri() {
+ return redirectUri;
+ }
+
+ /**
+ * @param redirectUri
+ * the redirectUri to set
+ */
+ public void setRedirectUri(String redirectUri) {
+ this.redirectUri = redirectUri;
+ }
+
+ /**
+ * @return the scope
+ */
+ public String getScope() {
+ return scope;
+ }
+
+ /**
+ * @param scope
+ * the scope to set
+ */
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ /**
+ * @return the clientID
+ */
+ public String getClientID() {
+ return clientID;
+ }
+
+ /**
+ * @param clientID
+ * the clientID to set
+ */
+ public void setClientID(String clientID) {
+ this.clientID = clientID;
+ }
+
+
+
+ /**
+ * @return the nonce
+ */
+ public String getNonce() {
+ return nonce;
+ }
+
+ /**
+ * @param nonce the nonce to set
+ */
+ public void setNonce(String nonce) {
+ this.nonce = nonce;
+ }
+
+ @Override
+ protected void populateSpecialParameters(HttpServletRequest request) throws OAuth20Exception {
+ this.setResponseType(this.getParam(request, OAuth20Constants.PARAM_RESPONSE_TYPE, true));
+ this.setState(this.getParam(request, OAuth20Constants.PARAM_STATE, true));
+ this.setRedirectUri(this.getParam(request, OAuth20Constants.PARAM_REDIRECT_URI, true));
+ this.setClientID(this.getParam(request, OAuth20Constants.PARAM_CLIENT_ID, true));
+ this.setScope(this.getParam(request, OAuth20Constants.PARAM_SCOPE, false));
+ this.setNonce(this.getParam(request, OAuth20Constants.PARAM_NONCE, false));
+
+ // check for response type
+ if (!this.responseType.equals(OAuth20Constants.RESPONSE_CODE)) {
+ throw new OAuth20ResponseTypeException();
+ }
+
+ // check state for invalid characters (like < > & ; ... javascript ... to prevent xss)
+ if (!OAuth20Util.isValidStateValue(this.getState())) {
+ throw new OAuth20WrongParameterException(OAuth20Constants.PARAM_STATE);
+ }
+
+ // check if client id and redirect uri are ok
+ try {
+ // OAOAUTH20 cannot be null at this point. check was done in base request
+ OAAuthParameter oAuthConfig = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(this.getOAURL());
+
+
+ if (!this.getClientID().equals(oAuthConfig.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_CLIENTID))
+ || !this.getRedirectUri().equals(oAuthConfig.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_REDIRECTURL))) {
+ throw new OAuth20AccessDeniedException();
+ }
+
+ this.setOnlineApplicationConfiguration(oAuthConfig);
+ Logger.info("Dispatch OpenIDConnect AuthRequest: ClientID=" + this.clientID);
+
+
+ } catch (ConfigurationException e) {
+ throw new OAuth20WrongParameterException(OAuth20Constants.PARAM_CLIENT_ID);
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes()
+ */
+ @Override
+ public List<Attribute> getRequestedAttributes() {
+ Map<String, String> reqAttr = new HashMap<String, String>();
+ for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION)
+ reqAttr.put(el, "");
+
+ try {
+ OAAuthParameter oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(getOAURL());
+
+ for (String s : scope.split(" ")) {
+ if (s.equalsIgnoreCase("profile")) {
+ for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuildersprofile())
+ reqAttr.put(el.getName(), "");
+
+ } else if (s.equalsIgnoreCase("eID")) {
+ for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuilderseid())
+ reqAttr.put(el.getName(), "");
+
+ } else if (s.equalsIgnoreCase("eID_gov")) {
+ for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuilderseidgov())
+ reqAttr.put(el.getName(), "");
+
+ } else if (s.equalsIgnoreCase("mandate")) {
+ for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuildersmandate())
+ reqAttr.put(el.getName(), "");
+
+ } else if (s.equalsIgnoreCase("stork")) {
+ for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuildersstork())
+ reqAttr.put(el.getName(), "");
+
+ }
+ }
+
+ return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.keySet().iterator());
+
+ } catch (ConfigurationException e) {
+ Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e);
+ return null;
+ }
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java
new file mode 100644
index 000000000..bd3fdb3e8
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.protocol;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
+import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.moduls.RequestImpl;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20InvalidRequestException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20OANotSupportedException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParameterException;
+import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
+import at.gv.egovernment.moa.logging.Logger;
+
+abstract class OAuth20BaseRequest extends RequestImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ protected Set<String> allowedParameters = new HashSet<String>();
+
+ protected OAuth20BaseRequest() {
+
+ }
+
+ protected String getParam(final HttpServletRequest request, final String name, final boolean isNeeded) throws OAuth20Exception {
+ String param = request.getParameter(name);
+ Logger.debug("Reading param " + name + " from HttpServletRequest with value " + param);
+
+ if (isNeeded && StringUtils.isEmpty(param)) {
+ throw new OAuth20WrongParameterException(name);
+ }
+
+ this.allowedParameters.add(name);
+
+ return param;
+ }
+
+ protected void populateParameters(final HttpServletRequest request) throws OAuth20Exception {
+
+ // moa id - load oa with client id!
+ try {
+ String oaURL = StringEscapeUtils.escapeHtml(this.getParam(request, OAuth20Constants.PARAM_CLIENT_ID, true));
+ if (!ParamValidatorUtils.isValidOA(oaURL)) {
+ throw new OAuth20WrongParameterException(OAuth20Constants.PARAM_CLIENT_ID);
+ }
+ this.setOAURL(oaURL);
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(oaURL);
+
+ if (oaParam == null) {
+ throw new OAuth20WrongParameterException(OAuth20Constants.PARAM_CLIENT_ID);
+ }
+ this.setTarget(oaParam.getTarget());
+
+ if (StringUtils.isEmpty(oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_CLIENTSECRET))
+ || StringUtils.isEmpty(oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_CLIENTID))
+ || StringUtils.isEmpty(oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_REDIRECTURL))) {
+ throw new OAuth20OANotSupportedException();
+ }
+ }
+ catch (ConfigurationException e) {
+ throw new OAuth20WrongParameterException(OAuth20Constants.PARAM_CLIENT_ID);
+ }
+
+ // oAuth
+ this.populateSpecialParameters(request);
+
+ // cleanup parameters
+ this.checkAllowedParameters(request);
+ }
+
+ private void checkAllowedParameters(final HttpServletRequest request) {
+ Logger.debug("Going to check for allowed parameters");
+ this.allowedParameters.add(OAuth20Constants.PARAM_MOA_ACTION);
+ this.allowedParameters.add(OAuth20Constants.PARAM_MOA_MOD);
+
+ @SuppressWarnings("rawtypes")
+ Iterator iter = request.getParameterMap().keySet().iterator();
+ while (iter.hasNext()) {
+ String name = (String) iter.next();
+ if (!this.allowedParameters.contains(name)) {
+
+ Logger.debug("Found wrong parameter: " + name);
+ throw new OAuth20WrongParameterException(name);
+ }
+ }
+
+ }
+
+ protected abstract void populateSpecialParameters(final HttpServletRequest request) throws OAuth20Exception;
+
+ public static OAuth20BaseRequest newInstance(final String action, final HttpServletRequest request, String sessionId, String transactionId) throws OAuth20Exception {
+ OAuth20BaseRequest res;
+
+ if (action.equals(OAuth20Protocol.AUTH_ACTION)) {
+ res = new OAuth20AuthRequest();
+
+ } else if (action.equals(OAuth20Protocol.TOKEN_ACTION)) {
+ res = new OAuth20TokenRequest();
+
+ } else {
+ throw new OAuth20InvalidRequestException();
+ }
+
+ res.setAction(action);
+ res.setModule(OAuth20Protocol.NAME);
+
+ res.populateParameters(request);
+ return res;
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java
new file mode 100644
index 000000000..56d86df72
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java
@@ -0,0 +1,215 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
+
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IModulInfo;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.util.ErrorResponseUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+import com.google.gson.JsonObject;
+
+import java.util.Arrays;
+
+public class OAuth20Protocol implements IModulInfo {
+
+ public static final String NAME = OAuth20Protocol.class.getName();
+ public static final String PATH = "id_oauth20";
+
+ public static final String AUTH_ACTION = "AUTH";
+ public static final String TOKEN_ACTION = "TOKEN";
+
+ public static final List<String> DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList(
+ new String[] {
+ PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME,
+ PVPConstants.BPK_NAME
+ });
+
+ private static HashMap<String, IAction> actions = new HashMap<String, IAction>();
+
+ static {
+ actions.put(AUTH_ACTION, new OAuth20AuthAction());
+ actions.put(TOKEN_ACTION, new OAuth20TokenAction());
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public String getPath() {
+ return PATH;
+ }
+
+ public IAction getAction(String action) {
+ return actions.get(action);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * at.gv.egovernment.moa.id.moduls.IModulInfo#preProcess(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse, java.lang.String)
+ */
+ public IRequest preProcess(HttpServletRequest request, HttpServletResponse resp, String action,
+ String sessionId, String transactionId) throws MOAIDException {
+ // validation is done inside creation
+ OAuth20BaseRequest res = OAuth20BaseRequest.newInstance(action, request, sessionId, transactionId);
+ Logger.debug("Created: " + res);
+ return res;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * at.gv.egovernment.moa.id.moduls.IModulInfo#canHandleRequest(javax.servlet.http.HttpServletRequest
+ * , javax.servlet.http.HttpServletResponse)
+ */
+ public IAction canHandleRequest(HttpServletRequest request, HttpServletResponse response) {
+ if (!StringUtils.isEmpty(request.getParameter("action"))) {
+ if (request.getParameter("action").equals(AUTH_ACTION)) {
+ return getAction(AUTH_ACTION);
+ } else if (request.getParameter("action").equals(TOKEN_ACTION)) {
+ return getAction(TOKEN_ACTION);
+ }
+ }
+
+ return null;// getAction(AUTH_ACTION);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IModulInfo#generateErrorMessage(java.lang.Throwable,
+ * javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
+ * at.gv.egovernment.moa.id.moduls.IRequest)
+ */
+ public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest)
+ throws Throwable {
+
+ // get error code and description
+ String errorCode;
+ String errorDescription;
+ String errorUri = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix()
+ +"/" + OAuth20Constants.ERRORPAGE;
+ String moaError = null;
+
+ ErrorResponseUtils errorUtils = ErrorResponseUtils.getInstance();
+
+ if (e instanceof OAuth20Exception) {
+ errorCode = ((OAuth20Exception) e).getErrorCode();
+ errorDescription = URLEncoder.encode(((OAuth20Exception) e).getMessageId() + ": " + e.getMessage(), "UTF-8");
+ moaError = errorUtils.mapInternalErrorToExternalError(((OAuth20Exception) e).getMessageId());
+
+ } else {
+ errorCode = OAuth20Constants.ERROR_SERVER_ERROR;
+ errorDescription = URLEncoder.encode(e.getMessage(), "UTF-8");
+ moaError = errorUtils.getResponseErrorCode(e);
+ }
+
+ String paramRedirect = null;
+ String state = null;
+ boolean isAuthRequest = false;
+ if (protocolRequest != null) {
+ if (protocolRequest instanceof OAuth20AuthRequest) {
+ isAuthRequest = true;
+
+ paramRedirect = ((OAuth20AuthRequest) protocolRequest).getRedirectUri();
+ state = ((OAuth20AuthRequest) protocolRequest).getState();
+ } else {
+ isAuthRequest = false;
+ }
+ } else {
+ String action = request.getParameter("action");
+ if (MiscUtil.isNotEmpty(action)) {
+ if (action.equals(AUTH_ACTION)) {
+
+ paramRedirect = request.getParameter(OAuth20Constants.PARAM_REDIRECT_URI);
+ state = request.getParameter(OAuth20Constants.PARAM_STATE);
+ isAuthRequest = true;
+ }
+ } else {
+ throw new MOAIDException("oauth20.01", new Object[] {});
+ }
+ }
+
+ // if (action.equals(AUTH_ACTION)) {
+ if (isAuthRequest) {
+ Logger.debug("Going to throw O OAuth20Exception for auth request");
+
+ StringBuilder url = new StringBuilder();
+
+ // check if given redirect url is ok
+ if (StringUtils.isNotEmpty(paramRedirect) && OAuth20Util.isUrl(paramRedirect)) {
+ url.append(paramRedirect);
+
+ // otherwise throw an
+ } else {
+ throw new MOAIDException("oauth20.01", new Object[] {});
+ }
+
+ OAuth20Util.addParameterToURL(url, OAuth20Constants.PARAM_ERROR, errorCode);
+ OAuth20Util.addParameterToURL(url, OAuth20Constants.PARAM_ERROR_DESCRIPTION, errorDescription);
+ if (MiscUtil.isNotEmpty(moaError))
+ OAuth20Util.addParameterToURL(url, OAuth20Constants.PARAM_ERROR_URI, errorUri + "#" + moaError);
+ OAuth20Util.addParameterToURL(url, OAuth20Constants.PARAM_STATE, state);
+
+ response.setContentType("text/html");
+ response.setStatus(HttpServletResponse.SC_FOUND);
+ response.addHeader("Location", url.toString());
+ Logger.debug("REDIRECT TO: " + url.toString());
+ return true;
+
+ } else {
+ Logger.debug("Going to throw O OAuth20Exception for token request");
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(OAuth20Constants.PARAM_ERROR, errorCode);
+ params.put(OAuth20Constants.PARAM_ERROR_DESCRIPTION, errorDescription);
+ params.put(OAuth20Constants.PARAM_ERROR_URI, errorUri + "#" + moaError);
+
+ // create response
+ JsonObject jsonObject = new JsonObject();
+ OAuth20Util.addProperytiesToJsonObject(jsonObject, params);
+ String jsonResponse = jsonObject.toString();
+ Logger.debug("JSON Response: " + jsonResponse);
+
+ // write respone to http response
+ response.setContentType("application/json");
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ response.getOutputStream().print(jsonResponse);
+ response.getOutputStream().close();
+
+ return true;
+ }
+
+ // return false;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * at.gv.egovernment.moa.id.moduls.IModulInfo#validate(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.moduls.IRequest)
+ */
+ public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) {
+ // we validate in the preProcess
+ return true;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java
new file mode 100644
index 000000000..2238a25e1
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.protocol;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20SessionObject;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ServerErrorException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20UnauthorizedClientException;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+import at.gv.egovernment.moa.logging.Logger;
+
+import com.google.gson.JsonObject;
+
+class OAuth20TokenAction implements IAction {
+
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp,
+ IAuthData authData) throws MOAIDException {
+
+
+ OAuth20SessionObject auth20SessionObject = null;
+ try {
+ OAuth20TokenRequest oAuthRequest = (OAuth20TokenRequest) req;
+
+ MOAReversionLogger.getInstance().logEvent(req, MOAIDEventConstants.AUTHPROTOCOL_OPENIDCONNECT_TOKENREQUEST);
+
+ try {
+ Logger.debug("Loaded OAuth20SessionObject from session: " + oAuthRequest.getCode());
+
+ auth20SessionObject =
+ AssertionStorage.getInstance().get(oAuthRequest.getCode(), OAuth20SessionObject.class);
+
+ } catch (MOADatabaseException e) {
+ throw new OAuth20UnauthorizedClientException();
+
+ }
+
+ // do checking for different grant types and code
+ if (auth20SessionObject == null || !auth20SessionObject.getCode().equals(oAuthRequest.getCode())) {
+ throw new OAuth20UnauthorizedClientException();
+ } else {
+ Logger.debug("Loaded of OAuth20SessionObject was successful");
+ }
+
+ // create response
+ JsonObject jsonObject = new JsonObject();
+ OAuth20Util.addProperytiesToJsonObject(jsonObject, auth20SessionObject.getAuthDataSession());
+ String jsonResponse = jsonObject.toString();
+ Logger.debug("JSON Response: " + jsonResponse);
+
+ // write respone to http response
+ httpResp.setContentType("application/json");
+ httpResp.setStatus(HttpServletResponse.SC_OK);
+ httpResp.getOutputStream().print(jsonResponse);
+ httpResp.getOutputStream().close();
+
+ return null;
+ }
+ catch (Exception e) {
+ Logger.error(e.getMessage(), e);
+ throw new OAuth20ServerErrorException();
+ }
+
+ finally {
+ if (auth20SessionObject != null) {
+ // destroy session for clean up
+
+ Logger.debug("Going to destroy session: " + auth20SessionObject.getCode());
+ AssertionStorage.getInstance().remove(auth20SessionObject.getCode());
+
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls
+ * .IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ public String getDefaultActionName() {
+ return OAuth20Protocol.TOKEN_ACTION;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java
new file mode 100644
index 000000000..6bebe5a6a
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.oauth20.protocol;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.opensaml.saml2.core.Attribute;
+
+import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20AccessDeniedException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20InvalidGrantException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParameterException;
+import at.gv.egovernment.moa.logging.Logger;
+
+class OAuth20TokenRequest extends OAuth20BaseRequest {
+
+ private static final long serialVersionUID = 1L;
+
+ private String code;
+ private String grantType;
+ private String clientID;
+ private String clientSecret;
+
+ /**
+ * @return the code
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
+ * @param code
+ * the code to set
+ */
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ /**
+ * @return the grantType
+ */
+ public String getGrantType() {
+ return grantType;
+ }
+
+ /**
+ * @param grantType
+ * the grantType to set
+ */
+ public void setGrantType(String grantType) {
+ this.grantType = grantType;
+ }
+
+ /**
+ * @return the clientID
+ */
+ public String getClientID() {
+ return clientID;
+ }
+
+ /**
+ * @param clientID
+ * the clientID to set
+ */
+ public void setClientID(String clientID) {
+ this.clientID = clientID;
+ }
+
+ /**
+ * @return the clientSecret
+ */
+ public String getClientSecret() {
+ return clientSecret;
+ }
+
+ /**
+ * @param clientSecret
+ * the clientSecret to set
+ */
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret = clientSecret;
+ }
+
+ @Override
+ protected void populateSpecialParameters(HttpServletRequest request) throws OAuth20Exception {
+ this.setCode(this.getParam(request, OAuth20Constants.RESPONSE_CODE, true));
+ this.setGrantType(this.getParam(request, OAuth20Constants.PARAM_GRANT_TYPE, true));
+ this.setClientID(this.getParam(request, OAuth20Constants.PARAM_CLIENT_ID, true));
+ this.setClientSecret(this.getParam(request, OAuth20Constants.PARAM_CLIENT_SECRET, true));
+
+ // check for grant type
+ if (!this.getGrantType().equals(OAuth20Constants.PARAM_GRANT_TYPE_VALUE_AUTHORIZATION_CODE)) {
+ throw new OAuth20InvalidGrantException();
+ }
+
+ // check if client id and secret are ok
+ try {
+ // OAOAUTH20 cannot be null at this point. check was done in base request
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(this.getOAURL());
+
+ if (!this.getClientID().equals(oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_CLIENTID))) {
+ throw new OAuth20AccessDeniedException();
+ }
+
+ if (!this.getClientSecret().equals(oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_OPENID_CLIENTSECRET))) {
+ throw new OAuth20AccessDeniedException();
+ }
+
+ this.setOnlineApplicationConfiguration(oaParam);
+
+ }
+ catch (ConfigurationException e) {
+ throw new OAuth20WrongParameterException(OAuth20Constants.PARAM_CLIENT_ID);
+ }
+
+ Logger.info("Dispatch OpenIDConnect TokenRequest: ClientID=" + this.clientID);
+
+ //add valid parameters
+ this.allowedParameters.add(OAuth20Constants.PARAM_SCOPE);
+ this.allowedParameters.add(OAuth20Constants.PARAM_REDIRECT_URI);
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes()
+ */
+ @Override
+ public List<Attribute> getRequestedAttributes() {
+ return null;
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo b/id/server/modules/moa-id-module-openID/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo
new file mode 100644
index 000000000..b653c91c3
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo
@@ -0,0 +1 @@
+at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20Protocol \ No newline at end of file
diff --git a/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java
new file mode 100644
index 000000000..6cf1e8280
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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 test.at.gv.egovernment.moa.id.auth.oauth;
+
+import iaik.security.ecc.provider.ECCProvider;
+
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import net.oauth.jsontoken.crypto.Signer;
+import net.oauth.jsontoken.crypto.Verifier;
+
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuth20SHA256Signer;
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuth20SHA256Verifier;
+import at.gv.egovernment.moa.util.KeyStoreUtils;
+
+public class CertTest {
+
+ /** KeyStore Path */
+ private String rsaKeyStorePath = "file:/D:/dev/work/exthex/workspace/OAuthTesting/resources/keys/test_keystore.jks";
+
+ private String ecdsaKeyStorePath = "file:/D:/dev/work/exthex/workspace/OAuthTesting/resources/keys/ECDSA_keystore.jks";
+
+ /** KeyStore Password */
+ private String keyStorePassword = "test12";
+
+ /** Specific Key Name as Credential */
+ private String keyName = "1";
+
+ /** Key password */
+ private String keyPassword = "test12";
+
+ private BasicX509Credential getCredentials(String keyStorePath) {
+ Assert.assertNotNull(keyStorePath);
+
+ // KeyStorePassword optional
+ // if (StringUtils.isEmpty(this.keyStorePassword))
+ // throw new SAMLException("No keyStorePassword specified");
+
+ Assert.assertNotNull(this.keyName);
+
+ // KeyStorePassword optional
+ // if (StringUtils.isEmpty(this.keyPassword))
+ // throw new SAMLException("No keyPassword specified");
+
+ KeyStore ks = null;
+ try {
+ ks = KeyStoreUtils.loadKeyStore(keyStorePath, this.keyStorePassword);
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ // return new KeyStoreX509CredentialAdapter(ks, keyName, keyPwd.toCharArray());
+ BasicX509Credential credential = null;
+ try {
+ X509Certificate certificate = (X509Certificate) ks.getCertificate(this.keyName);
+
+ PrivateKey privateKey = (PrivateKey) ks.getKey(this.keyName, this.keyPassword.toCharArray());
+
+ // System.out.println("KS Provider:" + privateKey.getClass());
+ credential = new BasicX509Credential();
+ credential.setEntityCertificate(certificate);
+ credential.setPrivateKey(privateKey);
+
+ System.out.println("Private Key: " + privateKey);
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+
+ }
+
+ return credential;
+ }
+
+ private void signAndVerify(BasicX509Credential credential) throws Exception {
+ String data = "someData";
+
+ Signer signer = new OAuth20SHA256Signer("signer1", keyName, credential.getPrivateKey());
+
+ byte[] signedData = signer.sign(data.getBytes());
+
+ Verifier verifier = new OAuth20SHA256Verifier(credential.getPublicKey());
+ verifier.verifySignature(data.getBytes(), signedData);
+ }
+
+ @Test
+ // (enabled = false)
+ public void testRSA() throws Exception {
+ BasicX509Credential credential = this.getCredentials(this.rsaKeyStorePath);
+
+ // System.out.println(credential);
+ this.signAndVerify(credential);
+ }
+
+ @Test
+ public void testECDSA() throws Exception {
+ ECCProvider.addAsProvider();
+
+ // Security.addProvider(new ECCProvider());
+ BasicX509Credential credential = this.getCredentials(this.ecdsaKeyStorePath);
+ this.signAndVerify(credential);
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20ErrorsTests.java b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20ErrorsTests.java
new file mode 100644
index 000000000..abfca4f36
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20ErrorsTests.java
@@ -0,0 +1,184 @@
+package test.at.gv.egovernment.moa.id.auth.oauth;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
+
+import com.google.api.client.extensions.java6.auth.oauth2.VerificationCodeReceiver;
+import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
+
+public class OAuth20ErrorsTests {
+
+ final static Logger log = LoggerFactory.getLogger(OAuth20ErrorsTests.class);
+
+ private static VerificationCodeReceiver receiver;
+
+ // base uri
+ private static String OAUTH2_BASE_URI = "https://localhost/moa-id-auth/";
+ // auth action
+ private static String OAUTH2_AUTH_URI = OAUTH2_BASE_URI + "oauth2/auth";
+ // token action
+ private static String OAUTH2_TOKEN_URI = OAUTH2_BASE_URI + "oauth2/token";
+
+ // client id
+ private static String CLIENT_ID = "http://test";
+ // client secret
+ private static String CLIENT_SECRET = "d435cf0a-3933-48f7-b142-339710c8f070";
+ // OAuth 2.0 scopes
+ //private static List<String> SCOPES = Arrays.asList("testScope1", "testScope2");
+ // state
+ private static String STATE = "testState";
+ // code
+ private static String CODE = "code";
+ // redirect uri
+ private static String REDIRECT_URI = "http://localhost:59542/Callback";
+
+ @BeforeMethod
+ public void beforeTest() throws Exception {
+ receiver = new LocalServerReceiver.Builder().setPort(59542).build();
+ // REDIRECT_URI = receiver.getRedirectUri();
+ // start
+ receiver.getRedirectUri();
+ }
+
+ @AfterMethod
+ public void afterTest() {
+ try {
+ receiver.stop();
+ }
+ catch (IOException e) {
+ }
+ }
+
+ private void checkParam(final String paramString, final String paramName) {
+ String[] help = paramString.split("=");
+ Assert.assertEquals(help[0], paramName);
+ Assert.assertTrue(StringUtils.isNotEmpty(help[1]));
+ }
+
+ private void checkParams(final String queryString) {
+ // System.out.println("QueryString: " + queryString);
+
+ System.out.println("Result url: " + queryString);
+
+ String[] params = queryString.split("&");
+
+ this.checkParam(params[0], OAuth20Constants.PARAM_ERROR);
+ this.checkParam(params[1], OAuth20Constants.PARAM_ERROR_DESCRIPTION);
+ // this.checkParam(params[2], OAuth20Constants.PARAM_ERROR_URI);
+ // this.checkParam(params[3], OAuth20Constants.PARAM_STATE);
+ this.checkParam(params[2], OAuth20Constants.PARAM_STATE);
+ }
+
+ class OAuthRequestParameters {
+ String redirectUri;
+ String clientId;
+ String responseType;
+ String scope;
+ String state;
+ String error;
+
+ public OAuthRequestParameters(String redirectUri, String clientId, String responseType, String scope, String state,
+ String error) {
+ this.redirectUri = redirectUri;
+ this.clientId = clientId;
+ this.responseType = responseType;
+ this.scope = scope;
+ this.state = state;
+ this.error = error;
+ }
+ }
+
+ @DataProvider(name = "parameter")
+ public Object[][] parameterProvider() {
+ // parameter is missing
+ // OAuthRequestParameters p0 = new OAuthRequestParameters(null, OA_URL, CLIENT_ID, CODE,
+ // "testScope1", null,
+ // "User authorization failed (invalid_request)");
+ // OAuthRequestParameters p1 = new OAuthRequestParameters(REDIRECT_URI, CLIENT_ID, CODE,
+ // "testScope1", STATE,
+ // "User authorization failed (invalid_request)");
+ OAuthRequestParameters p2 = new OAuthRequestParameters(REDIRECT_URI, null, CODE, "testScope1", STATE,
+ "User authorization failed (invalid_request)");
+ OAuthRequestParameters p3 = new OAuthRequestParameters(REDIRECT_URI, CLIENT_ID, null, "testScope1", STATE,
+ "User authorization failed (invalid_request)");
+ OAuthRequestParameters p4 = new OAuthRequestParameters(REDIRECT_URI, CLIENT_ID, CODE, null, STATE, null);
+ OAuthRequestParameters p5 = new OAuthRequestParameters(REDIRECT_URI, CLIENT_ID, CODE, "testScope1", null,
+ "User authorization failed (invalid_request)");
+
+ // wrong response type
+ OAuthRequestParameters p6 = new OAuthRequestParameters(REDIRECT_URI, CLIENT_ID, "WRONG_CODE", "testScope1", STATE,
+ "User authorization failed (unsupported_response_type)");
+ // wrong client id
+ OAuthRequestParameters p7 = new OAuthRequestParameters(REDIRECT_URI, "wrongClient", CODE, "testScope1", STATE,
+ "User authorization failed (invalid_request)");
+ // wrong redirect uri
+ // OAuthRequestParameters p9 = new OAuthRequestParameters("wrongURI", OA_URL, "wrongClient",
+ // CODE, "testScope1", STATE,
+ // "User authorization failed (access_denied)");
+
+ return new Object[][] { { p2 }, { p3 }, { p4 }, { p5 }, { p6 }, { p7 } };
+ }
+
+ @Test(dataProvider = "parameter", enabled = false)
+ public void testMissingParams(OAuthRequestParameters p) throws Exception {
+ StringBuilder url = new StringBuilder();
+ url.append(OAUTH2_AUTH_URI);
+
+ if (StringUtils.isNotEmpty(p.redirectUri)) OAuth20Util.addParameterToURL(url, "redirect_uri", p.redirectUri);
+ if (StringUtils.isNotEmpty(p.clientId)) OAuth20Util.addParameterToURL(url, "client_id", p.clientId);
+ if (StringUtils.isNotEmpty(p.responseType)) OAuth20Util.addParameterToURL(url, "response_type", p.responseType);
+ if (StringUtils.isNotEmpty(p.scope)) OAuth20Util.addParameterToURL(url, "scope", p.scope);
+ if (StringUtils.isNotEmpty(p.state)) OAuth20Util.addParameterToURL(url, "state", p.state);
+
+ String finalUrl = url.toString();
+ System.out.println("Calling: " + finalUrl);
+
+ HttpClient client = new HttpClient();
+ GetMethod get = new GetMethod(finalUrl);
+ int res = client.executeMethod(get);
+ Assert.assertEquals(res, HttpServletResponse.SC_OK);
+
+ // assert
+
+ if (p.error == null) {
+ Assert.assertFalse(get.getQueryString().contains("error"));
+ // receiver.waitForCode();
+ } else {
+ // check if all error params are returned
+ this.checkParams(get.getQueryString());
+ try {
+ receiver.waitForCode();
+ Assert.assertTrue(false);
+ }
+ catch (Exception e) {
+ Assert.assertEquals(e.getMessage(), p.error);
+ }
+ }
+ }
+
+ @Test(enabled = false)
+ public void testTokenErrorResponse() throws Exception {
+ HttpClient client = new HttpClient();
+ GetMethod get = new GetMethod(OAUTH2_TOKEN_URI + "&client_id=" + CLIENT_ID + "&client_secret=" + CLIENT_SECRET
+ + "&code=test&grant_type=authorization_code");
+ int res = client.executeMethod(get);
+
+ System.out.println(res);
+ System.out.println(get.getResponseBodyAsString());
+ }
+}
diff --git a/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20GoogleClientTestCase.java b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20GoogleClientTestCase.java
new file mode 100644
index 000000000..53c7ad496
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20GoogleClientTestCase.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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 test.at.gv.egovernment.moa.id.auth.oauth;
+
+import java.awt.Desktop;
+import java.awt.Desktop.Action;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URI;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
+import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl;
+import com.google.api.client.auth.oauth2.BearerToken;
+import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
+import com.google.api.client.auth.oauth2.TokenResponse;
+import com.google.api.client.auth.openidconnect.IdToken;
+import com.google.api.client.extensions.java6.auth.oauth2.VerificationCodeReceiver;
+import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
+import com.google.api.client.http.GenericUrl;
+import com.google.api.client.http.HttpExecuteInterceptor;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.jackson2.JacksonFactory;
+
+public class OAuth20GoogleClientTestCase {
+
+ final static Logger log = LoggerFactory.getLogger(OAuth20GoogleClientTestCase.class);
+
+ // private static FileDataStoreFactory DATA_STORE_FACTORY;
+
+ // Global instance of the HTTP transport.
+ private static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
+ // Global instance of the JSON factory.
+ private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
+
+ private static String ISS = "https://localhost/moa-id-auth/";
+
+ // base uri
+ //private static String OAUTH2_BASE_URI = ISS + "dispatcher";
+ // auth action
+ //private static String OAUTH2_AUTH_URI = OAUTH2_BASE_URI + "?mod=id_oauth20&action=AUTH";
+ private static String OAUTH2_AUTH_URI = ISS + "oauth2/auth";
+
+ // token action
+ //private static String OAUTH2_TOKEN_URI = OAUTH2_BASE_URI + "?mod=id_oauth20&action=TOKEN";
+ private static String OAUTH2_TOKEN_URI = ISS + "oauth2/token";
+
+ // client id
+ private static String CLIENT_ID = "http://test";
+ // client secret
+ private static String CLIENT_SECRET = "d435cf0a-3933-48f7-b142-339710c8f070";
+ // OAuth 2.0 scopes
+ private static final List<String> SCOPES = Arrays.asList("profile", "eID", "eID_gov", "mandate");
+
+ // open browser for bku login
+ private void openURL(String url) {
+ Assert.assertNotNull(url);
+ log.info("Please open the following URL in your browser:");
+ log.info(url);
+ if (Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+ if (desktop.isSupported(Action.BROWSE)) {
+ try {
+ desktop.browse(URI.create(url));
+ return;
+ }
+ catch (IOException e) {
+ // handled below
+ }
+ }
+ }
+
+ }
+
+ private TokenResponse authorize() throws Exception {
+ // set up a receiver for the callback
+ VerificationCodeReceiver receiver = new LocalServerReceiver.Builder().setPort(59542).build();
+
+ // create AuthorizationCodeFlow
+ GenericUrl token_uri = new GenericUrl(OAUTH2_TOKEN_URI);
+ HttpExecuteInterceptor credentials = new ClientParametersAuthentication(CLIENT_ID, CLIENT_SECRET);
+ AuthorizationCodeFlow flow = new AuthorizationCodeFlow.Builder(BearerToken.queryParameterAccessMethod(), HTTP_TRANSPORT,
+ JSON_FACTORY, token_uri, credentials, CLIENT_ID, OAUTH2_AUTH_URI).setScopes(SCOPES).build();
+ // .setDataStoreFactory(DATA_STORE_FACTORY)
+
+ // create AuthorizationCodeRequestUrl
+ try {
+ String redirectUri = receiver.getRedirectUri();
+ String state = new BigInteger(130, new SecureRandom()).toString(32);
+ AuthorizationCodeRequestUrl authorizationUrl = flow.newAuthorizationUrl().setRedirectUri(redirectUri).setState(state);
+
+ // open in browser
+ this.openURL(authorizationUrl.build());
+
+ // receive authorization code and exchange it for an access token
+ String code = receiver.waitForCode();
+ System.out.println(code);
+ TokenResponse response = flow.newTokenRequest(code).setRedirectUri(redirectUri).execute();
+ return response;
+ }
+ finally {
+ // if anything fails, stop the receiver
+ receiver.stop();
+ }
+
+ }
+
+ // eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJpc3MiOiJodHRwczovL2xvY2FsaG9zdC9tb2EtaWQtYXV0aC8iLCJleHAiOi02MzE5MDMsInN1YiI6IncveThQY2pNTHBFTGZmUHRTSDNtbmd6M24rRVx1MDAzZCIsImJpcnRoZGF0ZSI6IjE5ODUtMDItMDEiLCJmYW1pbHlfbmFtZSI6IkhpZXNzIiwiZ2l2ZW5fbmFtZSI6Ik1pY2hhZWwiLCJpYXQiOi02MzIyMDN9.Z_jveITHlTtktPOOV3n_sMbg50YQ4YcOEcSUs_RJ-4FGedj1sVxk9gmlUQcBPfQaBrPgC6RoiPLTy8CKu2PBClEyv9c9HdzIGqBjWzaTSNASx_QL5bfG4EQ8VZmSEI9d0whzlaBgkUFNfhx-Q2ZVh-g8SJ-0JO0zFR18OSRNTxPTJ4PPl0APqn2H-98sU331_zQKiZxNOvl_6OG26VoIYwEuW5m_N5tsf4lLAlqYcdHR3iNTeu8AkAOvlEwv7Z3BeeOiP4u-OWuc6VusWBPxaI2NwmDIoorpyIxY-wEFb4CWICuyk61Wlq1SCNdl-f-ODwJBK3rlj0IMlYbAjKSB0g
+ private void verifyIdToken(TokenResponse response) throws Exception {
+ String id_token = (String) response.getUnknownKeys().get("id_token");
+ log.info("going to parse id token: {}", id_token);
+
+ IdToken idToken = IdToken.parse(JSON_FACTORY, id_token);
+ Assert.assertTrue(idToken.verifyIssuer(ISS));
+
+ log.info(idToken.getPayload().toPrettyString());
+ log.info(idToken.getHeader().toPrettyString());
+
+ }
+
+ @Test(enabled = false)
+ public void testServerFlow() throws Exception {
+ TokenResponse response = this.authorize();
+ log.info(response.toPrettyString());
+
+ this.verifyIdToken(response);
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20UtilTest.java b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20UtilTest.java
new file mode 100644
index 000000000..8e18adc08
--- /dev/null
+++ b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/OAuth20UtilTest.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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 test.at.gv.egovernment.moa.id.auth.oauth;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
+
+public class OAuth20UtilTest {
+
+ @Test
+ public void validateURL() {
+ Assert.assertTrue(OAuth20Util.isUrl("file:/D:/dev/work/exthex/workspace/OAuthTesting/resources/keys/test_keystore.jks"));
+ Assert.assertTrue(OAuth20Util.isUrl("https://www.google.at/"));
+ Assert.assertTrue(OAuth20Util.isUrl("http://test"));
+ Assert.assertTrue(OAuth20Util.isUrl("http://localhost:59542/Callback"));
+
+
+ Assert.assertFalse(OAuth20Util.isUrl("http://"));
+ Assert.assertFalse(OAuth20Util.isUrl("123http://test"));
+ Assert.assertFalse(OAuth20Util.isUrl("test"));
+ }
+
+ @Test
+ public void validateState() {
+ // check state for invalid characters (like < > & ; ... javascript ... to prevent xss)
+
+ Assert.assertFalse(OAuth20Util.isValidStateValue("javascript"));
+ Assert.assertFalse(OAuth20Util.isValidStateValue("<Test"));
+ Assert.assertFalse(OAuth20Util.isValidStateValue("Test>"));
+ Assert.assertFalse(OAuth20Util.isValidStateValue("Tas<est"));
+ Assert.assertFalse(OAuth20Util.isValidStateValue("Te>st"));
+ Assert.assertFalse(OAuth20Util.isValidStateValue("Tes&t"));
+ Assert.assertFalse(OAuth20Util.isValidStateValue("Tes;t"));
+ Assert.assertTrue(OAuth20Util.isValidStateValue("secure_state"));
+ }
+
+
+ @Test
+ public void testExp() {
+ Pattern urlPattern = Pattern.compile("/oauth2/auth\\?(.*)$", Pattern.CASE_INSENSITIVE);
+ Matcher matcher = urlPattern.matcher("https://localhost/moa-id-auth/oauth2/auth?client_id=http://test&redirect_uri=http://localhost:59542/Callback&response_type=code&scope=profile%20eID%20eID_gov%20mandate&state=7gfnabf112ogg9segnnrfpi83q");
+ System.out.println(matcher.find());
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/pom.xml b/id/server/modules/moa-id-modules-saml1/pom.xml
new file mode 100644
index 000000000..a969098b6
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/pom.xml
@@ -0,0 +1,22 @@
+<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>MOA.id.server.modules</groupId>
+ <artifactId>moa-id-modules</artifactId>
+ <version>${moa-id-version}</version>
+ </parent>
+
+ <groupId>MOA.id.server.modules</groupId>
+ <artifactId>moa-id-module-saml1</artifactId>
+ <version>${moa-id-version}</version>
+ <packaging>jar</packaging>
+
+ <name>MOA ID-Module SAML1</name>
+
+ <properties>
+ <repositoryPath>${basedir}/../../../../repository</repositoryPath>
+ </properties>
+
+
+
+</project> \ No newline at end of file
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java
new file mode 100644
index 000000000..fc04fa9a7
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java
@@ -0,0 +1,458 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.auth.builder;
+
+import java.text.MessageFormat;
+import java.util.Calendar;
+import java.util.List;
+
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.exception.BuildException;
+import at.gv.egovernment.moa.id.auth.exception.ParseException;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.saml1.SAML1AuthenticationData;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+import at.gv.egovernment.moa.util.StringUtils;
+
+/**
+ * Builder for the authentication data <code>&lt;saml:Assertion&gt;</code>
+ * to be provided by the MOA ID Auth component.
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class AuthenticationDataAssertionBuilder extends AuthenticationAssertionBuilder implements Constants {
+
+ /** 5 minutes (=300 seconds) default length of the assertion */
+ private static int DEFAULT_CONDITIONS_LENGTH = 300;
+
+ /** private static String NL contains the NewLine representation in Java*/
+ private static final String NL = "\n";
+ /**
+ * XML template for the <code>&lt;saml:Assertion&gt;</code> to be built
+ */
+ private static final String AUTH_DATA =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + NL +
+ "<saml:Assertion xmlns:saml=''" + SAML_NS_URI + "'' xmlns:pr=''" + PD_NS_URI + "'' xmlns:xsi=''" + XSI_NS_URI + "''" +
+ " xmlns:si=''" + XSI_NS_URI + "''" +
+ " MajorVersion=''1'' MinorVersion=''0'' AssertionID=''{0}'' Issuer=''{1}'' IssueInstant=''{2}''>" + NL +
+ " <saml:AttributeStatement>" + NL +
+ " <saml:Subject>" + NL +
+ " <saml:NameIdentifier NameQualifier=''{3}''>{4}</saml:NameIdentifier>" + NL +
+ " <saml:SubjectConfirmation>" + NL +
+ " <saml:ConfirmationMethod>" + MOA_NS_URI + "cm</saml:ConfirmationMethod>" + NL +
+ " <saml:SubjectConfirmationData>{5}{6}</saml:SubjectConfirmationData>" + NL +
+ " </saml:SubjectConfirmation>" + NL +
+ " </saml:Subject>" + NL +
+ " <saml:Attribute AttributeName=''PersonData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{7}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''isQualifiedCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{8}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''bkuURL'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{9}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ "{10}" +
+ "{11}" +
+ "{12}" +
+ " </saml:AttributeStatement>" + NL +
+ "</saml:Assertion>";
+
+ /**
+ * XML template for the <code>&lt;saml:Assertion&gt;</code> to be built (with Conditions)
+ */
+ private static final String AUTH_DATA_WITH_CONDITIONS =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + NL +
+ "<saml:Assertion xmlns:saml=''" + SAML_NS_URI + "'' xmlns:pr=''" + PD_NS_URI + "'' xmlns:xsi=''" + XSI_NS_URI + "''" +
+ " xmlns:si=''" + XSI_NS_URI + "''" +
+ " MajorVersion=''1'' MinorVersion=''0'' AssertionID=''{0}'' Issuer=''{1}'' IssueInstant=''{2}''>" + NL +
+ "<saml:Conditions NotBefore=''{3}'' NotOnOrAfter=''{4}''/>" + NL +
+ " <saml:AttributeStatement>" + NL +
+ " <saml:Subject>" + NL +
+ " <saml:NameIdentifier NameQualifier=''{5}''>{6}</saml:NameIdentifier>" + NL +
+ " <saml:SubjectConfirmation>" + NL +
+ " <saml:ConfirmationMethod>" + MOA_NS_URI + "cm</saml:ConfirmationMethod>" + NL +
+ " <saml:SubjectConfirmationData>{7}{8}</saml:SubjectConfirmationData>" + NL +
+ " </saml:SubjectConfirmation>" + NL +
+ " </saml:Subject>" + NL +
+ " <saml:Attribute AttributeName=''PersonData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{9}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''isQualifiedCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{10}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''bkuURL'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{11}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ "{12}" +
+ "{13}" +
+ "{14}" +
+ " </saml:AttributeStatement>" + NL +
+ "</saml:Assertion>";
+
+ /**
+ * XML template for the <code>&lt;saml:Assertion&gt;</code> to be built
+ */
+ private static final String AUTH_DATA_MANDATE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + NL +
+ "<saml:Assertion xmlns:saml=''" + SAML_NS_URI + "'' xmlns:pr=''" + PD_NS_URI + "'' xmlns:xsi=''" + XSI_NS_URI + "''" +
+ " xmlns:si=''" + XSI_NS_URI + "''" +
+ " MajorVersion=''1'' MinorVersion=''0'' AssertionID=''{0}'' Issuer=''{1}'' IssueInstant=''{2}''>" + NL +
+ " <saml:AttributeStatement>" + NL +
+ " <saml:Subject>" + NL +
+ " <saml:NameIdentifier NameQualifier=''{3}''>{4}</saml:NameIdentifier>" + NL +
+ " <saml:SubjectConfirmation>" + NL +
+ " <saml:ConfirmationMethod>" + MOA_NS_URI + "cm</saml:ConfirmationMethod>" + NL +
+ " <saml:SubjectConfirmationData>{5}{6}</saml:SubjectConfirmationData>" + NL +
+ " </saml:SubjectConfirmation>" + NL +
+ " </saml:Subject>" + NL +
+ " <saml:Attribute AttributeName=''PersonData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{7}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''MandateData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{8}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''isQualifiedCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{9}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''bkuURL'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{10}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ "{11}" +
+ "{12}" +
+ "{13}" +
+ " </saml:AttributeStatement>" + NL +
+ "</saml:Assertion>";
+
+ /**
+ * XML template for the <code>&lt;saml:Assertion&gt;</code> to be built
+ */
+ private static final String AUTH_DATA_MANDATE_WITH_CONDITIONS =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + NL +
+ "<saml:Assertion xmlns:saml=''" + SAML_NS_URI + "'' xmlns:pr=''" + PD_NS_URI + "'' xmlns:xsi=''" + XSI_NS_URI + "''" +
+ " xmlns:si=''" + XSI_NS_URI + "''" +
+ " MajorVersion=''1'' MinorVersion=''0'' AssertionID=''{0}'' Issuer=''{1}'' IssueInstant=''{2}''>" + NL +
+ "<saml:Conditions NotBefore=''{3}'' NotOnOrAfter=''{4}''/>" + NL +
+ " <saml:AttributeStatement>" + NL +
+ " <saml:Subject>" + NL +
+ " <saml:NameIdentifier NameQualifier=''{5}''>{6}</saml:NameIdentifier>" + NL +
+ " <saml:SubjectConfirmation>" + NL +
+ " <saml:ConfirmationMethod>" + MOA_NS_URI + "cm</saml:ConfirmationMethod>" + NL +
+ " <saml:SubjectConfirmationData>{7}{8}</saml:SubjectConfirmationData>" + NL +
+ " </saml:SubjectConfirmation>" + NL +
+ " </saml:Subject>" + NL +
+ " <saml:Attribute AttributeName=''PersonData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{9}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''MandateData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{10}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''isQualifiedCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{11}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ " <saml:Attribute AttributeName=''bkuURL'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{12}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL +
+ "{13}" +
+ "{14}" +
+ "{15}" +
+ " </saml:AttributeStatement>" + NL +
+ "</saml:Assertion>";
+ /**
+ * XML template for the <code>&lt;saml:Attribute&gt;</code> named <code>"isPublicAuthority"</code>,
+ * to be inserted into the <code>&lt;saml:Assertion&gt;</code>
+ */
+ private static final String PUBLIC_AUTHORITY_ATT =
+ " <saml:Attribute AttributeName=''isPublicAuthority'' AttributeNamespace=''urn:oid:1.2.40.0.10.1.1.1''>" + NL +
+ " <saml:AttributeValue>{0}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL;
+
+ private static final String SIGNER_CERTIFICATE_ATT =
+ " <saml:Attribute AttributeName=''SignerCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL +
+ " <saml:AttributeValue>{0}</saml:AttributeValue>" + NL +
+ " </saml:Attribute>" + NL;
+
+ /**
+ * Constructor for AuthenticationDataAssertionBuilder.
+ */
+ public AuthenticationDataAssertionBuilder() {
+ super();
+ }
+
+ /**
+ * Builds the authentication data <code>&lt;saml:Assertion&gt;</code>.
+ *
+ * @param authData the <code>AuthenticationData</code> to build the
+ * <code>&lt;saml:Assertion&gt;</code> from
+ * @param xmlPersonData <code>lt;pr:Person&gt;</code> element as a String
+ * @param xmlAuthBlock authentication block to be included in a
+ * <code>lt;saml:SubjectConfirmationData&gt;</code> element; may include
+ * the <code>"Stammzahl"</code> or not; may be empty
+ * @param xmlIdentityLink the IdentityLink
+ * @param signerCertificateBase64 Base64 encoded certificate of the signer. Maybe
+ * an empty string if the signer certificate should not be provided.
+ * Will be ignored if the <code>businessService</code> parameter is
+ * set to <code>false</code>.
+ * @param businessService <code>true</code> if the online application is a
+ * business service, otherwise <code>false</code>
+ * @return the <code>&lt;saml:Assertion&gt;</code>
+ * @throws BuildException if an error occurs during the build process
+ */
+ public String build(
+ SAML1AuthenticationData authData,
+ String xmlPersonData,
+ String xmlAuthBlock,
+ String xmlIdentityLink,
+ String bkuURL,
+ String signerCertificateBase64,
+ boolean businessService,
+ List<ExtendedSAMLAttribute> extendedSAMLAttributes,
+ boolean useCondition,
+ int conditionLength)
+ throws BuildException
+ {
+
+ String isQualifiedCertificate = authData.isQualifiedCertificate() ? "true" : "false";
+
+ String publicAuthorityAttribute = "";
+ if (authData.isPublicAuthority()) {
+ String publicAuthorityIdentification = authData.getPublicAuthorityCode();
+ if (publicAuthorityIdentification == null)
+ publicAuthorityIdentification = "True";
+ publicAuthorityAttribute = MessageFormat.format(
+ PUBLIC_AUTHORITY_ATT, new Object[] { publicAuthorityIdentification });
+ }
+
+
+ String signerCertificateAttribute = "";
+ if (signerCertificateBase64 != "") {
+ signerCertificateAttribute = MessageFormat.format(
+ SIGNER_CERTIFICATE_ATT, new Object[] { signerCertificateBase64 });
+ }
+
+ String pkType;
+ String pkValue;
+ if (businessService) {
+ pkType = authData.getBPKType();
+ pkValue = authData.getBPK();
+
+ } else {
+ // <saml:NameIdentifier NameQualifier> always has the bPK as type/value
+ pkType = URN_PREFIX_BPK;
+ pkValue = authData.getBPK();
+ }
+
+// System.out.println("pkType; " + pkType);
+// System.out.println("pkValue; " + pkValue);
+
+ String assertion;
+ try {
+
+ if (!useCondition) {
+ assertion = MessageFormat.format(AUTH_DATA, new Object[] {
+ authData.getAssertionID(),
+ authData.getIssuer(),
+ authData.getIssueInstantString(),
+ pkType,
+ pkValue,
+ StringUtils.removeXMLDeclaration(xmlAuthBlock),
+ StringUtils.removeXMLDeclaration(xmlIdentityLink),
+ StringUtils.removeXMLDeclaration(xmlPersonData),
+ isQualifiedCertificate,
+ bkuURL,
+ publicAuthorityAttribute,
+ signerCertificateAttribute,
+ buildExtendedSAMLAttributes(extendedSAMLAttributes)});
+ }
+ else {
+ Calendar cal = Calendar.getInstance();
+ String notBefore = DateTimeUtils.buildDateTimeUTC(cal);
+ if (conditionLength <= 0)
+ cal.add(Calendar.SECOND, DEFAULT_CONDITIONS_LENGTH);
+ else
+ cal.add(Calendar.SECOND, conditionLength);
+
+ String notOnOrAfter = DateTimeUtils.buildDateTimeUTC(cal);
+
+ assertion = MessageFormat.format(AUTH_DATA_WITH_CONDITIONS, new Object[] {
+ authData.getAssertionID(),
+ authData.getIssuer(),
+ authData.getIssueInstantString(),
+ notBefore,
+ notOnOrAfter,
+ pkType,
+ pkValue,
+ StringUtils.removeXMLDeclaration(xmlAuthBlock),
+ StringUtils.removeXMLDeclaration(xmlIdentityLink),
+ StringUtils.removeXMLDeclaration(xmlPersonData),
+ isQualifiedCertificate,
+ bkuURL,
+ publicAuthorityAttribute,
+ signerCertificateAttribute,
+ buildExtendedSAMLAttributes(extendedSAMLAttributes)});
+ }
+
+
+ } catch (ParseException e) {
+ Logger.error("Error on building Authentication Data Assertion: " + e.getMessage());
+ throw new BuildException("builder.00", new Object[] { "Authentication Data Assertion", e.toString()});
+ }
+ return assertion;
+ }
+
+ /**
+ * Builds the authentication data <code>&lt;saml:Assertion&gt;</code>.
+ *
+ * @param authData the <code>AuthenticationData</code> to build the
+ * <code>&lt;saml:Assertion&gt;</code> from
+ * @param xmlPersonData <code>lt;pr:Person&gt;</code> element as a String
+ * @param xmlAuthBlock authentication block to be included in a
+ * <code>lt;saml:SubjectConfirmationData&gt;</code> element; may include
+ * the <code>"Stammzahl"</code> or not; may be empty
+ * @param xmlIdentityLink the IdentityLink
+ * @param signerCertificateBase64 Base64 encoded certificate of the signer. Maybe
+ * an empty string if the signer certificate should not be provided.
+ * Will be ignored if the <code>businessService</code> parameter is
+ * set to <code>false</code>.
+ * @param businessService <code>true</code> if the online application is a
+ * business service, otherwise <code>false</code>
+ * @return the <code>&lt;saml:Assertion&gt;</code>
+ * @throws BuildException if an error occurs during the build process
+ */
+ public String buildMandate(
+ SAML1AuthenticationData authData,
+ String xmlPersonData,
+ String xmlMandateData,
+ String xmlAuthBlock,
+ String xmlIdentityLink,
+ String bkuURL,
+ String signerCertificateBase64,
+ boolean businessService,
+ List<ExtendedSAMLAttribute> extendedSAMLAttributes,
+ boolean useCondition,
+ int conditionLength)
+ throws BuildException
+ {
+
+ String isQualifiedCertificate = authData.isQualifiedCertificate() ? "true" : "false";
+ String publicAuthorityAttribute = "";
+ if (authData.isPublicAuthority()) {
+ String publicAuthorityIdentification = authData.getPublicAuthorityCode();
+ if (publicAuthorityIdentification == null)
+ publicAuthorityIdentification = "True";
+ publicAuthorityAttribute = MessageFormat.format(
+ PUBLIC_AUTHORITY_ATT, new Object[] { publicAuthorityIdentification });
+ }
+
+
+ String signerCertificateAttribute = "";
+ if (signerCertificateBase64 != "") {
+ signerCertificateAttribute = MessageFormat.format(
+ SIGNER_CERTIFICATE_ATT, new Object[] { signerCertificateBase64 });
+ }
+
+ String pkType;
+ String pkValue;
+ if (businessService) {
+ pkType = authData.getBPKType();
+ pkValue = authData.getBPK();
+
+ } else {
+ // <saml:NameIdentifier NameQualifier> always has the bPK as type/value
+ pkType = URN_PREFIX_BPK;
+ pkValue = authData.getBPK();
+ }
+
+// System.out.println("pkType; " + pkType);
+// System.out.println("pkValue; " + pkValue);
+
+ String assertion;
+ try {
+
+
+
+ if (!useCondition) {
+ assertion = MessageFormat.format(AUTH_DATA_MANDATE, new Object[] {
+ authData.getAssertionID(),
+ authData.getIssuer(),
+ authData.getIssueInstantString(),
+ pkType,
+ pkValue,
+ StringUtils.removeXMLDeclaration(xmlAuthBlock),
+ StringUtils.removeXMLDeclaration(xmlIdentityLink),
+ StringUtils.removeXMLDeclaration(xmlPersonData),
+ StringUtils.removeXMLDeclaration(xmlMandateData),
+ isQualifiedCertificate,
+ bkuURL,
+ publicAuthorityAttribute,
+ signerCertificateAttribute,
+ buildExtendedSAMLAttributes(extendedSAMLAttributes)});
+ }
+ else {
+ Calendar cal = Calendar.getInstance();
+ String notBefore = DateTimeUtils.buildDateTimeUTC(cal);
+ if (conditionLength <= 0)
+ cal.add(Calendar.SECOND, DEFAULT_CONDITIONS_LENGTH);
+ else
+ cal.add(Calendar.SECOND, conditionLength);
+
+ String notOnOrAfter = DateTimeUtils.buildDateTimeUTC(cal);
+
+ assertion = MessageFormat.format(AUTH_DATA_MANDATE_WITH_CONDITIONS, new Object[] {
+ authData.getAssertionID(),
+ authData.getIssuer(),
+ authData.getIssueInstantString(),
+ notBefore,
+ notOnOrAfter,
+ pkType,
+ pkValue,
+ StringUtils.removeXMLDeclaration(xmlAuthBlock),
+ StringUtils.removeXMLDeclaration(xmlIdentityLink),
+ StringUtils.removeXMLDeclaration(xmlPersonData),
+ StringUtils.removeXMLDeclaration(xmlMandateData),
+ isQualifiedCertificate,
+ bkuURL,
+ publicAuthorityAttribute,
+ signerCertificateAttribute,
+ buildExtendedSAMLAttributes(extendedSAMLAttributes)});
+ }
+
+
+
+
+
+
+ } catch (ParseException e) {
+ Logger.error("Error on building Authentication Data Assertion: " + e.getMessage());
+ throw new BuildException("builder.00", new Object[] { "Authentication Data Assertion", e.toString()});
+ }
+ return assertion;
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java
new file mode 100644
index 000000000..2019b0d20
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.saml1;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet;
+import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationImpl;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.URLEncoder;
+
+public class GetArtifactAction implements IAction {
+
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq,
+ HttpServletResponse httpResp, IAuthData obj) throws AuthenticationException {
+
+ String oaURL = (String) req.getOAURL();
+
+ String sourceID = null;
+ if (req instanceof SAML1RequestImpl) {
+ SAML1RequestImpl saml1req = (SAML1RequestImpl) req;
+ sourceID = saml1req.getSourceID();
+
+ }
+
+ SAML1AuthenticationData authData;
+ if (obj instanceof SAML1AuthenticationData) {
+ authData = (SAML1AuthenticationData) obj;
+
+ } else {
+ Logger.error("AuthDate is NOT of type SAML1AuthenticationData.");
+ throw new AuthenticationException("AuthDate is NOT of type SAML1AuthenticationData.", new Object[]{});
+ }
+
+ try {
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(oaURL);
+
+ SAML1AuthenticationServer saml1server = SAML1AuthenticationServer.getInstace();
+
+ // add other stork attributes to MOA assertion if available
+ if(null != authData.getStorkAttributes()) {
+ List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(authData.getStorkAttributes());
+ authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes);
+ Logger.info("MOA assertion assembled and SAML Artifact generated.");
+ }
+
+ String samlArtifactBase64 = saml1server.BuildSAMLArtifact(oaParam, authData, sourceID);
+
+ if (authData.isSsoSession()) {
+ String url = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix() + "/RedirectServlet";
+ url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(oaURL, "UTF-8"));
+ if (!oaParam.getBusinessService())
+ url = addURLParameter(url, MOAIDAuthConstants.PARAM_TARGET, URLEncoder.encode(req.getTarget(), "UTF-8"));
+ url = addURLParameter(url, MOAIDAuthConstants.PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
+ url = httpResp.encodeRedirectURL(url);
+
+ httpResp.setContentType("text/html");
+ httpResp.setStatus(302);
+ httpResp.addHeader("Location", url);
+
+ } else {
+ String redirectURL = oaURL;
+ if (!oaParam.getBusinessService()) {
+ redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_TARGET,
+ URLEncoder.encode(req.getTarget(), "UTF-8"));
+
+ }
+
+ redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_SAMLARTIFACT,
+ URLEncoder.encode(samlArtifactBase64, "UTF-8"));
+ redirectURL = httpResp.encodeRedirectURL(redirectURL);
+ httpResp.setContentType("text/html");
+ httpResp.setStatus(302);
+ httpResp.addHeader("Location", redirectURL);
+ Logger.debug("REDIRECT TO: " + redirectURL);
+ }
+
+ SLOInformationInterface sloInformation =
+ new SLOInformationImpl(authData.getAssertionID(), null, null, req.requestedModule());
+
+ return sloInformation;
+
+ } catch (Exception ex) {
+ Logger.error("SAML1 Assertion build error", ex);
+ throw new AuthenticationException("SAML1 Assertion build error.", new Object[]{}, ex);
+ }
+
+ }
+
+ protected static String addURLParameter(String url, String paramname,
+ String paramvalue) {
+ String param = paramname + "=" + paramvalue;
+ if (url.indexOf("?") < 0)
+ return url + "?" + param;
+ else
+ return url + "&" + param;
+ }
+
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq,
+ HttpServletResponse httpResp) {
+ return true;
+ }
+
+ public String getDefaultActionName() {
+ return SAML1Protocol.GETARTIFACT;
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java
new file mode 100644
index 000000000..2b4aaf458
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.saml1;
+
+import java.util.Calendar;
+
+import org.apache.axis.AxisFault;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.id.auth.builder.SAMLResponseBuilder;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.util.ErrorResponseUtils;
+import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+/**
+ * Web service for picking up authentication data created in the MOA-ID Auth component.
+ *
+ * @author Paul Ivancsics
+ * @version $Id: GetAuthenticationDataService.java 1233 2012-01-26 21:59:33Z kstranacher $
+ * @see at.gv.egovernment.moa.id.auth.AuthenticationServer#getAuthenticationData
+ */
+public class GetAuthenticationDataService implements Constants {
+
+ /**
+ * Constructor for GetAuthenticationDataService.
+ */
+ public GetAuthenticationDataService() {
+ super();
+ }
+
+ /**
+ * Takes a <code>lt;samlp:Request&gt;</code> containing a
+ * <code>SAML artifact</code> and returns the corresponding
+ * authentication data <code>lt;saml:Assertion&gt;</code>
+ * (obtained from the <code>AuthenticationServer</code>),
+ * enclosed in a <code>lt;samlp:Response&gt;</code>.
+ * <br/>Bad requests are mapped into various <code>lt;samlp:StatusCode&gt;</code>s,
+ * possibly containing enclosed sub-<code>lt;samlp:StatusCode&gt;</code>s.
+ * The status codes are defined in the SAML specification.
+ *
+ * @param requests request elements of type <code>lt;samlp:Request&gt;</code>;
+ * only 1 request element is allowed
+ * @return response element of type <code>lt;samlp:Response&gt;</code>,
+ * packed into an <code>Element[]</code>
+ * @throws AxisFault thrown when an error occurs in assembling the
+ * <code>lt;samlp:Response&gt;</code>
+ */
+ public Element[] Request(Element[] requests)
+ throws AxisFault {
+
+ Element request = requests[0];
+ Element[] responses = new Element[1];
+ String requestID = "";
+ String statusCode = "";
+ String subStatusCode = null;
+ String statusMessageCode = null;
+ String statusMessage = null;
+ String samlAssertion = "";
+ if (requests.length > 1) {
+ // more than 1 request given as parameter
+ statusCode = "samlp:Requester";
+ subStatusCode = "samlp:TooManyResponses";
+ statusMessageCode = "1201";
+ }
+ else {
+ try {
+ DOMUtils.validateElement(request, ALL_SCHEMA_LOCATIONS, null);
+ NodeList samlArtifactList = XPathUtils.selectNodeList(request, "samlp:AssertionArtifact");
+ if (samlArtifactList.getLength() == 0) {
+ // no SAML artifact given in request
+ statusCode = "samlp:Requester";
+ statusMessageCode = "1202";
+ }
+ else if (samlArtifactList.getLength() > 1) {
+ // too many SAML artifacts given in request
+ statusCode = "samlp:Requester";
+ subStatusCode = "samlp:TooManyResponses";
+ statusMessageCode = "1203";
+ }
+
+ else {
+ Element samlArtifactElem = (Element)samlArtifactList.item(0);
+ requestID = request.getAttribute("RequestID");
+ String samlArtifact = DOMUtils.getText(samlArtifactElem);
+ SAML1AuthenticationServer saml1server = SAML1AuthenticationServer.getInstace();
+
+ try {
+
+ samlAssertion = saml1server.getSaml1AuthenticationData(samlArtifact);
+
+ // success
+ statusCode = "samlp:Success";
+ statusMessageCode = "1200";
+ }
+
+ catch (ClassCastException ex) {
+
+ try {
+ Throwable error = saml1server.getErrorResponse(samlArtifact);
+ statusCode = "samlp:Responder";
+
+ ErrorResponseUtils errorUtils = ErrorResponseUtils.getInstance();
+
+ if (error instanceof MOAIDException) {
+ statusMessageCode = ((MOAIDException)error).getMessageId();
+ statusMessage = StringEscapeUtils.escapeXml(((MOAIDException)error).getMessage());
+
+ } else {
+ statusMessage = StringEscapeUtils.escapeXml(error.getMessage());
+ }
+ subStatusCode = errorUtils.getResponseErrorCode(error);
+
+ } catch (Exception e) {
+ //no authentication data for given SAML artifact
+ statusCode = "samlp:Requester";
+ subStatusCode = "samlp:ResourceNotRecognized";
+ statusMessage = ex.toString();
+ }
+
+ }
+
+ catch (AuthenticationException ex) {
+ //no authentication data for given SAML artifact
+ statusCode = "samlp:Requester";
+ subStatusCode = "samlp:ResourceNotRecognized";
+ statusMessage = ex.toString();
+ }
+ }
+ }
+ catch (Throwable t) {
+ // invalid request format
+ statusCode = "samlp:Requester";
+ statusMessageCode = "1204";
+ }
+ }
+
+ try {
+ String responseID = Random.nextRandom();
+ String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar.getInstance());
+
+ if (statusMessage == null)
+ statusMessage = MOAIDMessageProvider.getInstance().getMessage(statusMessageCode, null);
+ responses[0] = new SAMLResponseBuilder().build(
+ responseID, requestID, issueInstant, statusCode, subStatusCode, statusMessage, samlAssertion);
+
+ }
+ catch (MOAIDException e) {
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ }
+ catch (Throwable t) {
+ MOAIDException e = new MOAIDException("1299", null, t);
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ }
+ return responses;
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java
new file mode 100644
index 000000000..d48c0a9bb
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.saml1;
+
+import java.text.ParseException;
+import java.util.List;
+
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+
+/**
+ * Encapsulates authentication data contained in a <code>&lt;saml:Assertion&gt;</code>.
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+
+public class SAML1AuthenticationData extends AuthenticationData {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1042697056735596866L;
+/**
+ * major version number of the SAML assertion
+ */
+ private int majorVersion;
+ /**
+ * minor version number of the SAML assertion
+ */
+ private int minorVersion;
+ /**
+ * identifier for this assertion
+ */
+ private String assertionID;
+/**
+ * @return the majorVersion
+ */
+
+ private String samlAssertion = null;
+
+ private List<ExtendedSAMLAttribute> extendedSAMLAttributesOA;
+
+
+ public SAML1AuthenticationData() {
+ this.setMajorVersion(1);
+ this.setMinorVersion(0);
+ this.setAssertionID(Random.nextRandom());
+ }
+
+
+ //this method is only required for MOA-ID Proxy 2.0 Release.
+ //TODO: remove it, if MOA-ID Proxy is not supported anymore.
+ public String getWBPK() {
+ return getBPK();
+ }
+
+public int getMajorVersion() {
+ return majorVersion;
+}
+/**
+ * @param majorVersion the majorVersion to set
+ */
+public void setMajorVersion(int majorVersion) {
+ this.majorVersion = majorVersion;
+}
+/**
+ * @return the minorVersion
+ */
+public int getMinorVersion() {
+ return minorVersion;
+}
+/**
+ * @param minorVersion the minorVersion to set
+ */
+public void setMinorVersion(int minorVersion) {
+ this.minorVersion = minorVersion;
+}
+/**
+ * @return the assertionID
+ */
+public String getAssertionID() {
+ return assertionID;
+}
+/**
+ * @param assertionID the assertionID to set
+ */
+public void setAssertionID(String assertionID) {
+ this.assertionID = assertionID;
+}
+
+public void setIssueInstant(String date) {
+ try {
+ setIssueInstant(DateTimeUtils.parseDateTime(date));
+
+ } catch (ParseException e) {
+ Logger.error("Parse IssueInstant element FAILED.", e);
+
+ }
+}
+
+/**
+ * @return the samlAssertion
+ */
+public String getSamlAssertion() {
+ return samlAssertion;
+}
+
+/**
+ * @param samlAssertion the samlAssertion to set
+ */
+public void setSamlAssertion(String samlAssertion) {
+ this.samlAssertion = samlAssertion;
+}
+
+/**
+ * @return the extendedSAMLAttributesOA
+ */
+public List<ExtendedSAMLAttribute> getExtendedSAMLAttributesOA() {
+ return extendedSAMLAttributesOA;
+}
+
+/**
+ * @param extendedSAMLAttributesOA the extendedSAMLAttributesOA to set
+ */
+public void setExtendedSAMLAttributesOA(
+ List<ExtendedSAMLAttribute> extendedSAMLAttributesOA) {
+ this.extendedSAMLAttributesOA = extendedSAMLAttributesOA;
+}
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java
new file mode 100644
index 000000000..e70e71d49
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java
@@ -0,0 +1,592 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.saml1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder;
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder;
+import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.BuildException;
+import at.gv.egovernment.moa.id.auth.exception.ParseException;
+import at.gv.egovernment.moa.id.auth.exception.ServiceException;
+import at.gv.egovernment.moa.id.auth.exception.ValidateException;
+import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser;
+import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+//import at.gv.egovernment.moa.id.util.IdentityLinkReSigner;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.MiscUtil;
+import at.gv.egovernment.moa.util.StringUtils;
+import at.gv.util.xsd.persondata.IdentificationType;
+import at.gv.util.xsd.persondata.IdentificationType.Value;
+import at.gv.util.xsd.persondata.PersonNameType;
+import at.gv.util.xsd.persondata.PersonNameType.FamilyName;
+import at.gv.util.xsd.persondata.PhysicalPersonType;
+
+public class SAML1AuthenticationServer extends AuthenticationServer {
+
+ private static SAML1AuthenticationServer instance;
+
+ public static SAML1AuthenticationServer getInstace() {
+ if (instance == null)
+ instance = new SAML1AuthenticationServer();
+
+ return instance;
+ }
+
+ private static AssertionStorage authenticationDataStore = AssertionStorage.getInstance();
+
+
+ /**
+ * time out in milliseconds used by {@link cleanup} for authentication data
+ * store
+ */
+ private static final long authDataTimeOut = 2 * 60 * 1000; // default 2 minutes
+
+
+ public Throwable getErrorResponse(String samlArtifact) throws AuthenticationException {
+ try {
+ new SAMLArtifactParser(samlArtifact).parseAssertionHandle();
+
+ } catch (ParseException ex) {
+ throw new AuthenticationException("1205", new Object[] {
+ samlArtifact, ex.toString() });
+ }
+ Throwable error = null;
+ synchronized (authenticationDataStore) {
+ try {
+ error = authenticationDataStore
+ .get(samlArtifact, Throwable.class);
+
+ authenticationDataStore.remove(samlArtifact);
+
+ } catch (MOADatabaseException e) {
+ Logger.error("Assertion not found for SAML Artifact: " + samlArtifact);
+ throw new AuthenticationException("1206", new Object[] { samlArtifact });
+ }
+
+ }
+
+ return error;
+ }
+
+ /**
+ * Retrieves <code>AuthenticationData</code> indexed by the SAML artifact.
+ * The <code>AuthenticationData</code> is deleted from the store upon end of
+ * this call.
+ *
+ * @return <code>AuthenticationData</code>
+ */
+ public String getSaml1AuthenticationData(String samlArtifact)
+ throws AuthenticationException {
+ try {
+ new SAMLArtifactParser(samlArtifact).parseAssertionHandle();
+
+ } catch (ParseException ex) {
+ throw new AuthenticationException("1205", new Object[] {
+ samlArtifact, ex.toString() });
+ }
+ String authData = null;
+ synchronized (authenticationDataStore) {
+ // System.out.println("assertionHandle: " + assertionHandle);
+
+ try {
+ authData = authenticationDataStore
+ .get(samlArtifact, String.class, authDataTimeOut);
+
+ } catch (MOADatabaseException e) {
+ Logger.error("Assertion not found for SAML Artifact: " + samlArtifact);
+ throw new AuthenticationException("1206", new Object[] { samlArtifact });
+ }
+ }
+
+ authenticationDataStore.remove(samlArtifact);
+
+ Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact);
+
+ return authData;
+ }
+
+ public String BuildErrorAssertion(Throwable error, IRequest protocolRequest)
+ throws BuildException, MOADatabaseException {
+
+ String samlArtifact = new SAMLArtifactBuilder().build(
+ protocolRequest.getOAURL(), protocolRequest.getRequestID(),
+ null);
+
+ authenticationDataStore.put(samlArtifact, error);
+
+ return samlArtifact;
+ }
+
+ public String BuildSAMLArtifact(OAAuthParameter oaParam,
+ SAML1AuthenticationData authData, String sourceID)
+ throws ConfigurationException, BuildException, AuthenticationException {
+
+ //Load SAML1 Parameter from OA config
+ SAML1ConfigurationParameters saml1parameter = oaParam.getSAML1Parameter();
+
+ boolean useCondition = saml1parameter.isUseCondition();
+ int conditionLength = saml1parameter.getConditionLength();
+
+ try {
+
+ //set BASE64 encoded signer certificate
+ String signerCertificateBase64 = "";
+ if (saml1parameter.isProvideCertificate()) {
+ byte[] signerCertificate = authData.getSignerCertificate();
+ if (signerCertificate != null) {
+
+ signerCertificateBase64 = Base64Utils
+ .encode(signerCertificate);
+ } else {
+ Logger.info("\"provideCertificate\" is \"true\", but no signer certificate available");
+ }
+ }
+
+ //set prPersion
+ boolean provideStammzahl = saml1parameter.isProvideStammzahl()
+ || oaParam.getBusinessService();
+
+ String prPerson = "";
+ String ilAssertion = "";
+ if (authData.getIdentityLink() != null) {
+ prPerson = new PersonDataBuilder().build(authData.getIdentityLink(),
+ provideStammzahl);
+
+ //set IdentityLink for assortion
+ if (saml1parameter.isProvideIdentityLink()) {
+ ilAssertion = authData.getIdentityLink().getSerializedSamlAssertion();
+
+ if (!provideStammzahl)
+ ilAssertion = StringUtils.replaceAll(ilAssertion, authData.getIdentityLink()
+ .getIdentificationValue(), "");
+ }
+ } else {
+ Logger.info("No IdentityLink available! Build attribute 'PersonDate' from givenname, familyname and dateofbirth. ");
+ PhysicalPersonType person = new PhysicalPersonType();
+ PersonNameType name = new PersonNameType();
+ person.setName(name);
+ FamilyName familyName = new FamilyName();
+ name.getFamilyName().add(familyName );
+ IdentificationType id = new IdentificationType();
+ person.getIdentification().add(id );
+ Value value = new Value();
+ id.setValue(value );
+
+ id.setType(authData.getIdentificationType());
+ //add baseID if it is requested and available
+ if ( MiscUtil.isNotEmpty(authData.getIdentificationValue()) &&
+ saml1parameter.isProvideIdentityLink() )
+ value.setValue(authData.getIdentificationValue());
+ else
+ value.setValue("");
+
+ familyName.setValue(authData.getFamilyName());
+ familyName.setPrimary("undefined");
+ name.getGivenName().add(authData.getGivenName());
+ person.setDateOfBirth(authData.getFormatedDateOfBirth());
+
+ JAXBContext jc = JAXBContext.newInstance("at.gv.util.xsd.persondata");
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
+// m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
+// public String getPreferredPrefix(String arg0, String arg1, boolean arg2) {
+// if (Constants.PD_NS_URI.equals(arg0))
+// return Constants.PD_PREFIX;
+// else
+// return arg1;
+// }
+// });
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ m.marshal(
+ new JAXBElement<PhysicalPersonType>(new QName(Constants.PD_NS_URI,"Person"), PhysicalPersonType.class, person),
+ stream);
+ prPerson = StringUtils.removeXMLDeclaration(new String(stream.toByteArray(), "UTF-8"));
+ stream.close();
+
+
+
+ }
+
+ //set Authblock
+ String authBlock = "";
+ if (authData.getAuthBlock() != null) {
+ authBlock = saml1parameter.isProvideAUTHBlock() ? authData.getAuthBlock() : "";
+
+ } else {
+ Logger.info("\"provideAuthBlock\" is \"true\", but no authblock available");
+
+ }
+
+ String samlAssertion;
+ if (authData.isUseMandate()) {
+ List<ExtendedSAMLAttribute> oaAttributes = authData.getExtendedSAMLAttributesOA();
+
+ //only provide full mandate if it is included.
+ //In case of federation only a short mandate could be include
+ if (saml1parameter.isProvideFullMandatorData()
+ && authData.getMISMandate().isFullMandateIncluded()) {
+
+ try {
+
+ ExtendedSAMLAttribute[] extendedSAMLAttributes = addExtendedSamlAttributes(
+ authData.getMISMandate(), oaParam.getBusinessService(),
+ saml1parameter.isProvideStammzahl());
+
+ if (extendedSAMLAttributes != null) {
+
+ String identifier = "MISService";
+ String friendlyName ="MISService";
+
+ int length = extendedSAMLAttributes.length;
+ for (int i = 0; i < length; i++) {
+ ExtendedSAMLAttribute samlAttribute = extendedSAMLAttributes[i];
+
+ Object value = verifySAMLAttribute(samlAttribute, i, identifier,
+ friendlyName);
+
+ if ((value instanceof String) || (value instanceof Element)) {
+ switch (samlAttribute.getAddToAUTHBlock()) {
+ case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK:
+ replaceExtendedSAMLAttribute(oaAttributes, samlAttribute);
+ break;
+ case ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK:
+ replaceExtendedSAMLAttribute(oaAttributes, samlAttribute);
+ break;
+ case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY:
+ break;
+ default:
+ Logger
+ .info("Invalid return value from method \"getAddToAUTHBlock()\" ("
+ + samlAttribute.getAddToAUTHBlock()
+ + ") in SAML attribute number "
+ + (i + 1)
+ + " for infobox " + identifier);
+ throw new ValidateException("validator.47", new Object[] {
+ friendlyName, String.valueOf((i + 1)) });
+ }
+ } else {
+ Logger
+ .info("The type of SAML-Attribute number "
+ + (i + 1)
+ + " returned from "
+ + identifier
+ + "-infobox validator is not valid. Must be either \"java.Lang.String\""
+ + " or \"org.w3c.dom.Element\"");
+ throw new ValidateException("validator.46", new Object[] {
+ identifier, String.valueOf((i + 1)) });
+ }
+ }
+ }
+
+ } catch (SAXException e) {
+ throw new AuthenticationException("auth.16",
+ new Object[] { GET_MIS_SESSIONID }, e);
+ } catch (IOException e) {
+ throw new AuthenticationException("auth.16",
+ new Object[] { GET_MIS_SESSIONID }, e);
+ } catch (ParserConfigurationException e) {
+ throw new AuthenticationException("auth.16",
+ new Object[] { GET_MIS_SESSIONID }, e);
+ } catch (TransformerException e) {
+ throw new AuthenticationException("auth.16",
+ new Object[] { GET_MIS_SESSIONID }, e);
+ }
+ }
+
+ String mandateDate = generateMandateDate(oaParam, authData);
+
+ samlAssertion = new AuthenticationDataAssertionBuilder().buildMandate(
+ authData,
+ prPerson,
+ mandateDate,
+ authBlock,
+ ilAssertion,
+ authData.getBkuURL(),
+ signerCertificateBase64,
+ oaParam.getBusinessService(),
+ oaAttributes,
+ useCondition,
+ conditionLength);
+
+ } else {
+ samlAssertion = new AuthenticationDataAssertionBuilder().build(
+ authData,
+ prPerson,
+ authBlock,
+ ilAssertion,
+ authData.getBkuURL(),
+ signerCertificateBase64,
+ oaParam.getBusinessService(),
+ authData.getExtendedSAMLAttributesOA(),
+ useCondition,
+ conditionLength);
+ }
+
+ //authData.setSamlAssertion(samlAssertion);
+
+ String samlArtifact = new SAMLArtifactBuilder().build(
+ authData.getIssuer(), Random.nextRandom(),
+ sourceID);
+
+ storeAuthenticationData(samlArtifact, samlAssertion);
+
+ Logger.info("Anmeldedaten angelegt, SAML Artifakt " + samlArtifact);
+ return samlArtifact;
+
+ } catch (Throwable ex) {
+ throw new BuildException("builder.00", new Object[] {
+ "AuthenticationData", ex.toString() }, ex);
+ }
+
+ }
+
+ private String generateMandateDate(OAAuthParameter oaParam, AuthenticationData authData
+ ) throws AuthenticationException, BuildException,
+ ParseException, ConfigurationException, ServiceException,
+ ValidateException {
+
+ if (authData == null)
+ throw new AuthenticationException("auth.10", new Object[] {
+ REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID });
+
+ IdentityLink tempIdentityLink = null;
+
+ Element mandate = authData.getMandate();
+
+ if (authData.isUseMandate()) {
+ tempIdentityLink = new IdentityLink();
+ Element mandator = ParepUtils.extractMandator(mandate);
+ String dateOfBirth = "";
+ Element prPerson = null;
+ String familyName = "";
+ String givenName = "";
+ String identificationType = "";
+ String identificationValue = "";
+ if (mandator != null) {
+ boolean physical = ParepUtils.isPhysicalPerson(mandator);
+ if (physical) {
+ familyName = ParepUtils.extractText(mandator,
+ "descendant-or-self::pr:Name/pr:FamilyName/text()");
+ givenName = ParepUtils.extractText(mandator,
+ "descendant-or-self::pr:Name/pr:GivenName/text()");
+ dateOfBirth = ParepUtils
+ .extractMandatorDateOfBirth(mandator);
+ } else {
+ familyName = ParepUtils.extractMandatorFullName(mandator);
+ }
+ identificationType = ParepUtils.getIdentification(mandator,
+ "Type");
+ identificationValue = ParepUtils.extractMandatorWbpk(mandator);
+
+ prPerson = ParepUtils.extractPrPersonOfMandate(mandate);
+ if (physical
+ && oaParam.getBusinessService()
+ && identificationType != null
+ && Constants.URN_PREFIX_BASEID
+ .equals(identificationType)) {
+ // now we calculate the wbPK and do so if we got it from the
+ // BKU
+
+
+ //load IdentityLinkDomainType from OAParam
+ String type = oaParam.getIdentityLinkDomainIdentifier();
+ if (type.startsWith(Constants.URN_PREFIX_WBPK + "+"))
+ identificationType = type;
+ else
+ identificationType = Constants.URN_PREFIX_WBPK + "+"
+ + type;
+
+
+ identificationValue = new BPKBuilder().buildWBPK(
+ identificationValue, identificationType);
+ ParepUtils
+ .HideStammZahlen(prPerson, true, null, null, true);
+ }
+
+ tempIdentityLink.setDateOfBirth(dateOfBirth);
+ tempIdentityLink.setFamilyName(familyName);
+ tempIdentityLink.setGivenName(givenName);
+ tempIdentityLink.setIdentificationType(identificationType);
+ tempIdentityLink.setIdentificationValue(identificationValue);
+ tempIdentityLink.setPrPerson(prPerson);
+ try {
+ tempIdentityLink.setSamlAssertion(authData.getIdentityLink()
+ .getSamlAssertion());
+ } catch (Exception e) {
+ throw new ValidateException("validator.64", null);
+ }
+
+ }
+
+ }
+
+ Element mandatePerson = tempIdentityLink.getPrPerson();
+
+ String mandateData = null;
+ try {
+
+ boolean provideStammzahl = oaParam.getSAML1Parameter().isProvideStammzahl();
+
+ String oatargetType;
+
+ if(oaParam.getBusinessService()) {
+ if (oaParam.getIdentityLinkDomainIdentifier().startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_))
+ oatargetType = oaParam.getIdentityLinkDomainIdentifier();
+ else
+ oatargetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_+oaParam.getIdentityLinkDomainIdentifier();
+
+ } else {
+ oatargetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget();
+ }
+
+ Element prIdentification = (Element) mandatePerson
+ .getElementsByTagNameNS(Constants.PD_NS_URI,
+ "Identification").item(0);
+
+ if (!oatargetType.equals(tempIdentityLink.getIdentificationType())) {
+
+ String isPrPerson = mandatePerson.getAttribute("xsi:type");
+
+ if (!StringUtils.isEmpty(isPrPerson)) {
+ if (isPrPerson.equalsIgnoreCase("pr:PhysicalPerson")) {
+ String baseid = getBaseId(mandatePerson);
+ Element identificationBpK = createIdentificationBPK(mandatePerson,
+ baseid, oaParam.getTarget());
+
+ if (!provideStammzahl) {
+ prIdentification.getFirstChild().setTextContent("");
+ }
+
+ mandatePerson.insertBefore(identificationBpK,
+ prIdentification);
+ }
+ }
+
+ } else {
+
+// Element identificationBpK = mandatePerson.getOwnerDocument()
+// .createElementNS(Constants.PD_NS_URI, "Identification");
+// Element valueBpK = mandatePerson.getOwnerDocument().createElementNS(
+// Constants.PD_NS_URI, "Value");
+//
+// valueBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode(
+// tempIdentityLink.getIdentificationValue()));
+// Element typeBpK = mandatePerson.getOwnerDocument().createElementNS(
+// Constants.PD_NS_URI, "Type");
+// typeBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode(
+// "urn:publicid:gv.at:cdid+bpk"));
+// identificationBpK.appendChild(valueBpK);
+// identificationBpK.appendChild(typeBpK);
+//
+// mandatePerson.insertBefore(identificationBpK, prIdentification);
+ }
+
+
+ mandateData = DOMUtils.serializeNode(mandatePerson);
+
+ } catch (TransformerException e1) {
+ throw new AuthenticationException("auth.16",
+ new Object[] { GET_MIS_SESSIONID });
+ } catch (IOException e1) {
+ throw new AuthenticationException("auth.16",
+ new Object[] { GET_MIS_SESSIONID });
+ }
+
+ return mandateData;
+ }
+
+
+
+
+ /**
+ * Stores authentication data indexed by the assertion handle contained in
+ * the given saml artifact.
+ *
+ * @param samlArtifact
+ * SAML artifact
+ * @param authData
+ * authentication data
+ * @throws AuthenticationException
+ * when SAML artifact is invalid
+ */
+ private void storeAuthenticationData(String samlArtifact,
+ String samlAssertion) throws AuthenticationException {
+
+ try {
+ SAMLArtifactParser parser = new SAMLArtifactParser(samlArtifact);
+ // check type code 0x0001
+ byte[] typeCode = parser.parseTypeCode();
+ if (typeCode[0] != 0 || typeCode[1] != 1)
+ throw new AuthenticationException("auth.06",
+ new Object[] { samlArtifact });
+ parser.parseAssertionHandle();
+
+ synchronized (authenticationDataStore) {
+ Logger.debug("Assertion stored for SAML Artifact: "
+ + samlArtifact);
+ authenticationDataStore.put(samlArtifact, samlAssertion);
+ }
+
+ } catch (AuthenticationException ex) {
+ throw ex;
+
+ } catch (Throwable ex) {
+ throw new AuthenticationException("auth.06",
+ new Object[] { samlArtifact });
+ }
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java
new file mode 100644
index 000000000..7416dfb00
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.saml1;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.exception.ProtocolNotActiveException;
+import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
+import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IModulInfo;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import at.gv.egovernment.moa.util.URLEncoder;
+
+public class SAML1Protocol extends MOAIDAuthConstants implements IModulInfo {
+
+ public static final String NAME = SAML1Protocol.class.getName();
+ public static final String PATH = "id_saml1";
+
+ public static final String GETARTIFACT = "GetArtifact";
+
+ public static final List<String> DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList(
+ new String[] {
+ PVPConstants.BPK_NAME,
+ PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME,
+ PVPConstants.GIVEN_NAME_NAME,
+ PVPConstants.PRINCIPAL_NAME_NAME,
+ PVPConstants.BIRTHDATE_NAME,
+ PVPConstants.EID_CCS_URL_NAME,
+ PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME,
+ PVPConstants.EID_IDENTITY_LINK_NAME,
+ PVPConstants.EID_SOURCE_PIN_NAME,
+ PVPConstants.EID_SOURCE_PIN_TYPE_NAME
+ });
+
+ private static HashMap<String, IAction> actions = new HashMap<String, IAction>();
+
+ static {
+
+ actions.put(GETARTIFACT, new GetArtifactAction());
+
+ instance = new SAML1Protocol();
+ }
+
+ private static SAML1Protocol instance = null;
+
+ public static SAML1Protocol getInstance() {
+ if (instance == null) {
+ instance = new SAML1Protocol();
+ }
+ return instance;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public String getPath() {
+ return PATH;
+ }
+
+ public IRequest preProcess(HttpServletRequest request,
+ HttpServletResponse response, String action,
+ String sessionId, String transactionId) throws MOAIDException {
+ SAML1RequestImpl config = new SAML1RequestImpl();
+
+ if (!AuthConfigurationProviderFactory.getInstance().getAllowedProtocols().isSAML1Active()) {
+ Logger.info("SAML1 is deaktivated!");
+ throw new ProtocolNotActiveException("auth.22", new Object[] { "SAML 1" });
+
+ }
+
+ String oaURL = (String) request.getParameter(PARAM_OA);
+ //oaURL = StringEscapeUtils.escapeHtml(oaURL);
+
+ String target = (String) request.getParameter(PARAM_TARGET);
+ target = StringEscapeUtils.escapeHtml(target);
+
+ String sourceID = request.getParameter(PARAM_SOURCEID);
+ sourceID = StringEscapeUtils.escapeHtml(sourceID);
+
+ //the target parameter is used to define the OA in SAML1 standard
+ if (target != null && target.startsWith("http")) {
+ oaURL = target;
+ target = null;
+ }
+
+ if (MiscUtil.isEmpty(oaURL)) {
+ Logger.info("Receive SAML1 request with no OA parameter. Authentication STOPPED!");
+ throw new WrongParametersException("StartAuthentication", PARAM_OA,
+ "auth.12");
+
+ }
+
+ if (!ParamValidatorUtils.isValidOA(oaURL))
+ throw new WrongParametersException("StartAuthentication", PARAM_OA,
+ "auth.12");
+
+ config.setOAURL(oaURL);
+
+ Logger.info("Dispatch SAML1 Request: OAURL=" + oaURL);
+
+ if (!ParamValidatorUtils.isValidSourceID(sourceID))
+ throw new WrongParametersException("StartAuthentication", PARAM_SOURCEID, "auth.12");
+
+
+ //load Target only from OA config
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(oaURL);
+
+ if (oaParam == null)
+ throw new InvalidProtocolRequestException("auth.00",
+ new Object[] { null });
+
+ SAML1ConfigurationParameters saml1 = oaParam.getSAML1Parameter();
+ if (saml1 == null || !(saml1.isIsActive() != null && saml1.isIsActive()) ) {
+ Logger.info("Online-Application " + oaURL + " can not use SAML1 for authentication.");
+ throw new InvalidProtocolRequestException("auth.00",
+ new Object[] { null });
+ }
+ config.setOnlineApplicationConfiguration(oaParam);
+ config.setSourceID(sourceID);
+
+ MOAReversionLogger.getInstance().logEvent(sessionId, transactionId, MOAIDEventConstants.AUTHPROTOCOL_SAML1_AUTHNREQUEST);
+
+ if (MiscUtil.isNotEmpty(target))
+ config.setTarget(target);
+
+ else
+ config.setTarget(oaParam.getTarget());
+
+
+ return config;
+ }
+
+ public boolean generateErrorMessage(Throwable e,
+ HttpServletRequest request, HttpServletResponse response,
+ IRequest protocolRequest)
+ throws Throwable{
+
+ OAAuthParameter oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(protocolRequest.getOAURL());
+ if (!oa.getSAML1Parameter().isProvideAllErrors())
+ return false;
+
+ else {
+ SAML1AuthenticationServer saml1authentication = SAML1AuthenticationServer.getInstace();
+ String samlArtifactBase64 = saml1authentication.BuildErrorAssertion(e, protocolRequest);
+
+ String url = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix() + "/RedirectServlet";
+ url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(protocolRequest.getOAURL(), "UTF-8"));
+ url = addURLParameter(url, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
+ url = response.encodeRedirectURL(url);
+
+ response.setContentType("text/html");
+ response.setStatus(302);
+ response.addHeader("Location", url);
+ Logger.debug("REDIRECT TO: " + url);
+
+ return true;
+ }
+ }
+
+ public IAction getAction(String action) {
+ return actions.get(action);
+ }
+
+ public IAction canHandleRequest(HttpServletRequest request,
+ HttpServletResponse response) {
+ return null;
+ }
+
+ public boolean validate(HttpServletRequest request,
+ HttpServletResponse response, IRequest pending) {
+
+ return true;
+ }
+
+ protected static String addURLParameter(String url, String paramname,
+ String paramvalue) {
+ String param = paramname + "=" + paramvalue;
+ if (url.indexOf("?") < 0)
+ return url + "?" + param;
+ else
+ return url + "&" + param;
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java
new file mode 100644
index 000000000..5370573a7
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.saml1;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opensaml.saml2.core.Attribute;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters;
+import at.gv.egovernment.moa.id.moduls.RequestImpl;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SAML1RequestImpl extends RequestImpl {
+
+ private static final long serialVersionUID = -4961979968425683115L;
+
+ private String sourceID = null;
+
+ /**
+ * @return the sourceID
+ */
+ public String getSourceID() {
+ return sourceID;
+ }
+
+ /**
+ * @param sourceID the sourceID to set
+ */
+ public void setSourceID(String sourceID) {
+ this.sourceID = sourceID;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes()
+ */
+ @Override
+ public List<Attribute> getRequestedAttributes() {
+
+ List<String> reqAttr = new ArrayList<String>();
+ reqAttr.addAll(SAML1Protocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION);
+
+ try {
+ OAAuthParameter oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(getOAURL());
+ SAML1ConfigurationParameters saml1 = oa.getSAML1Parameter();
+ if (saml1 != null) {
+ if (saml1.isProvideAUTHBlock())
+ reqAttr.add(PVPConstants.EID_AUTH_BLOCK_NAME);
+
+ if (saml1.isProvideCertificate())
+ reqAttr.add(PVPConstants.EID_SIGNER_CERTIFICATE_NAME);
+
+ if (saml1.isProvideFullMandatorData())
+ reqAttr.add(PVPConstants.MANDATE_FULL_MANDATE_NAME);
+ }
+
+ return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.iterator());
+
+ } catch (ConfigurationException e) {
+ Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e);
+ return null;
+ }
+
+
+ }
+
+}
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo b/id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo
new file mode 100644
index 000000000..5bff0dbc2
--- /dev/null
+++ b/id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo
@@ -0,0 +1 @@
+at.gv.egovernment.moa.id.protocols.saml1.SAML1Protocol \ No newline at end of file
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
new file mode 100644
index 000000000..25cb952d7
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationImpl;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.peps.auth.commons.*;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The AttributeCollector Action tries to get all requested attributes from a set of {@link AttributeProvider} Plugins.
+ * The class is called whenever the {@link AuthenticationRequest} Action is invoked and checks for missing attributes.
+ * Furthermore, the class can handle direct posts. That is when the class triggers an attribute query which needs user
+ * interaction, redirect to another portal, etc. The redirect will hit here and the class can continue to fetch attributes.
+ *
+ * TODO how do we treat mandatory and optional attributes?
+ */
+public class AttributeCollector implements IAction {
+
+ /**
+ * The Constant ARTIFACT_ID.
+ */
+ private static final String ARTIFACT_ID = "artifactId";
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.auth.data.AuthenticationSession)
+ */
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
+
+ // - fetch the container
+ String artifactId = (String) httpReq.getParameter(ARTIFACT_ID);
+ DataContainer container;
+ try {
+ container = AssertionStorage.getInstance().get(artifactId, DataContainer.class);
+ } catch (MOADatabaseException e) {
+ Logger.error("Error fetching incomplete Stork response from temporary storage. Most likely a timeout occured.", e);
+ throw new MOAIDException("stork.11", null);
+ }
+
+
+ if (httpReq.getParameter("SAMLResponse") != null) {
+ Logger.info("Got SAML response from external attribute provider.");
+
+ MOASTORKResponse STORK2Response = new MOASTORKResponse();
+
+ //extract STORK Response from HTTP Request
+ byte[] decSamlToken;
+ try {
+ decSamlToken = PEPSUtil.decodeSAMLToken(httpReq.getParameter("SAMLResponse"));
+ } catch (NullPointerException e) {
+ if (httpReq.getRemoteHost().contains("129.27.142")) {
+ Logger.warn("Availability check by " + httpReq.getRemoteHost() + " on URI: " + httpReq.getRequestURI());
+ } else {
+ Logger.error("Unable to retrieve STORK Request for host: " + httpReq.getRemoteHost() + " and URI: " + httpReq.getRequestURI(), e);
+ }
+ throw new MOAIDException("stork.04", null);
+ }
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+
+ STORKAuthnResponse authnResponse = null;
+
+
+ // check if valid authn response is contained
+ try {
+ authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, httpReq.getRemoteAddr());
+ } catch (STORKSAMLEngineException ex) {
+ Logger.error("Unable to validate Stork AuthenticationResponse: " + ex.getMessage());
+ }
+
+ STORK2Response.setSTORKAuthnResponseToken(decSamlToken);
+
+ // check if the attributes are provided for the same person from request
+ // requires presence of eIdentifier for unambigious correlation
+ Logger.debug("Checking if the attribute relates to the correct person..");
+ try {
+ String remoteEIdentifier= authnResponse.getPersonalAttributeList().get("eIdentifier").getValue().get(0);
+ String localEidentifier= container.getResponse().getStorkAuthnResponse().getPersonalAttributeList().get("eIdentifier").getValue().get(0);
+ if (!remoteEIdentifier.equals(localEidentifier)) {
+ Logger.error("The attribute is not provided for the same person!");
+ throw new MOAIDException("stork.25", null);
+ }
+ } catch (NullPointerException ex) {
+ Logger.warn("Could not check the correlation of attributes from external provider. Ignoring the check.");
+ //Logger.debug(ex);
+ //throw new MOAIDException("stork.04", null); // TODO revise message, raise exception when ehvd checked
+ }
+
+ if (authnResponse.getPersonalAttributeList().size() > 0) {
+ Logger.info("Response from external attribute provider contains " + authnResponse.getPersonalAttributeList().size() + " attributes.");
+ container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), authnResponse.getPersonalAttributeList()));
+ }
+
+ }
+
+ // end addition
+
+
+ // read configuration parameters of OA
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(container.getRequest().getAssertionConsumerServiceURL());
+ if (oaParam == null)
+ throw new AuthenticationException("stork.12", new Object[]{container.getRequest().getAssertionConsumerServiceURL()});
+
+ // find the attribute provider plugin that can handle the response
+ IPersonalAttributeList newAttributes = null;
+
+ Iterator<AttributeProvider> attibuteProvidersInterator = AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs());
+ while(attibuteProvidersInterator.hasNext())
+ try {
+ newAttributes = attibuteProvidersInterator.next().parse(httpReq);
+
+ // stop as soon as we hit a capable plugin
+ break;
+ } catch (UnsupportedAttributeException e1) {
+ // the current provider cannot find anything familiar within the
+ // provided httpreq. Try the next one.
+ }
+
+ if (null == newAttributes) {
+ // we do not have a provider which is capable of fetching something
+ // from the received httpreq.
+ Logger.error("No attribute could be retrieved from the response the attribute provider gave us.");
+ }
+
+ // - insert the embedded attribute(s) into the container
+ if (null != newAttributes)
+ container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), newAttributes));
+
+ // see if we need some more attributes
+ SLOInformationImpl sloInfo = (SLOInformationImpl) processRequest(container, httpReq, httpResp, authData, oaParam);
+
+ if (sloInfo == null) {
+ sloInfo = new SLOInformationImpl(null, null, null, req.requestedModule());
+ }
+
+ return sloInfo;
+
+ }
+
+ /**
+ * Checks if there are missing attributes and tries to fetch them. If there are no more attribute to fetch,
+ * this very method creates and sends the protocol result to the asking S-PEPS.
+ *
+ * @param container the {@link DataContainer} representing the status of the overall query.
+ * @return the string
+ * @throws MOAIDException
+ */
+ public SLOInformationInterface processRequest(DataContainer container, HttpServletRequest request, HttpServletResponse response, IAuthData authData, OAAuthParameter oaParam) throws MOAIDException {
+ // check if there are attributes we need to fetch
+
+ IPersonalAttributeList requestAttributeList = container.getRequest().getPersonalAttributeList();
+ IPersonalAttributeList responseAttributeList = container.getResponse().getPersonalAttributeList();
+ List<PersonalAttribute> missingAttributes = new ArrayList<PersonalAttribute>();
+ Logger.debug("aquire list of missing attributes");
+ for (PersonalAttribute current : requestAttributeList)
+ if (!responseAttributeList.containsKey(current.getName())) {
+ if(null == current.getStatus() || (null != current.getStatus() && !current.getStatus().equals(AttributeStatusType.WITHHELD.value()))) {
+ // add the ones we need
+ missingAttributes.add(current);
+ Logger.debug("add " + current.getName() + " to the list of missing attributes");
+ }
+ } else {
+ // remove the ones we do not want to share from the response list
+ if(null != current.getStatus() && current.getStatus().equals(AttributeStatusType.WITHHELD.value())) {
+ responseAttributeList.remove(current.getName());
+ Logger.debug("remove " + current.getName() + " from the list of resulting attributes because the user does not want to disclose the data");
+ }
+ }
+
+ Logger.info("collecting attributes...");
+ Logger.debug("found " + missingAttributes.size() + " missing attributes");
+
+ // Try to get all missing attributes
+ try {
+ // for each attribute still missing
+ for (PersonalAttribute currentAttribute : missingAttributes) {
+
+ /*
+ * prefill attributes with "notAvailable". If we get them later, we override the value and status.
+ * This way, there is no error case in which an attribute is left unanswered.
+ */
+ IPersonalAttributeList aquiredAttributes = new PersonalAttributeList();
+ currentAttribute.setStatus(AttributeStatusType.NOT_AVAILABLE.value());
+ aquiredAttributes.add((PersonalAttribute) currentAttribute.clone());
+ container.getResponse().setPersonalAttributeList(
+ addOrUpdateAll(container.getResponse().getPersonalAttributeList(), aquiredAttributes));
+ // - check if we can find a suitable AttributeProvider Plugin
+
+ Iterator<AttributeProvider> attibuteProvidersInterator = AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs());
+ while(attibuteProvidersInterator.hasNext()) {
+ AttributeProvider currentProvider = attibuteProvidersInterator.next();
+
+ // build a section of attribute provider's predefined attributes and missing attributes
+ // only missing attributes that can be handled by attribute provider will be sent to it
+ List<PersonalAttribute> currentProviderConfiguredAttributes = new ArrayList<PersonalAttribute>();
+ for (String attributeName : currentProvider.getSupportedAttributeNames()) {
+ for (PersonalAttribute missingAttribute : missingAttributes) {
+ if (missingAttribute.getName().equals(attributeName)) {
+ currentProviderConfiguredAttributes.add(missingAttribute);
+ break;
+ }
+ }
+ }
+
+ try {
+ // - hand over control to the suitable plugin
+ Logger.info(currentProvider.getClass().getSimpleName() + " called to handle attribute '" + currentAttribute.getName() + "'");
+
+ //aquiredAttributes = currentProvider.acquire(currentAttribute, container.getRequest().getSpCountry(), moasession);
+ //aquiredAttributes = currentProvider.acquire(missingAttributes, container.getRequest().getSpCountry(), moasession);
+ aquiredAttributes = currentProvider.acquire(currentProviderConfiguredAttributes, container.getRequest(), authData);
+
+ Logger.info(currentProvider.getClass().getSimpleName() + " can handle attribute '" + currentAttribute.getName() + "'");
+ break;
+ } catch (UnsupportedAttributeException e) {
+ // ok, try the next attributeprovider
+ Logger.info(currentProvider.getClass().getSimpleName() + " could not handle attribute '" + currentAttribute.getName() + "'");
+ } catch (MOAIDException e) {
+ // the current plugin had an error. Try the next one.
+ Logger.info(currentProvider.getClass().getSimpleName() + " could not handle attribute '" + currentAttribute.getName() + "' due to an error");
+ }
+ }
+
+ // check if we could fetch the attribute
+ if (null == aquiredAttributes) {
+ // if not
+ Logger.error("We have no suitable plugin for obtaining the attribute '" + currentAttribute.getName() + "'");
+ } else
+ // else, update any existing attributes
+ container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), aquiredAttributes));
+ }
+ Logger.info("collecting attributes done");
+
+ // ask for consent if necessary
+ new ConsentEvaluator().generateSTORKResponse(response, container);
+
+ return null; // AssertionId
+ // TODO
+
+ } catch (ExternalAttributeRequestRequiredException e) {
+ // the attribute request is ongoing and requires an external service.
+ try {
+ // memorize the container again
+ Logger.debug("prepare putting the container into temporary storage...");
+
+ // - generate new key
+ String newArtifactId = new SecureRandomIdentifierGenerator()
+ .generateIdentifier();
+ // - put container in temporary store.
+ AssertionStorage.getInstance().put(newArtifactId, container);
+
+ Logger.debug("...successful");
+
+ Logger.info(e.getAp().getClass().getSimpleName() + " is going to ask an external service provider for the requested attributes");
+
+ // add container-key to redirect embedded within the return URL
+ e.getAp().performRedirect(AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix() + "/stork2/ResumeAuthentication?" + ARTIFACT_ID + "=" + newArtifactId, request, response, oaParam);
+
+ } catch (Exception e1) {
+ // TODO should we return the response as is to the PEPS?
+ Logger.error("Error putting incomplete Stork response into temporary storage", e1);
+ e1.printStackTrace();
+ throw new MOAIDException("stork.11", null);
+ }
+
+ //TODO: in case of Single LogOut -> SLO information has to be stored
+ return null; // TODO what to do here?
+ }
+ }
+
+ /**
+ * Adds or updates all {@link PersonalAttribute} objects given in {@code source} to/in {@code target}.
+ *
+ * @param target the target
+ * @param source the source
+ * @return
+ * @throws MOAIDException
+ */
+ private PersonalAttributeList addOrUpdateAll(IPersonalAttributeList target, IPersonalAttributeList source) throws MOAIDException {
+
+ PersonalAttributeList updatedList = new PersonalAttributeList();
+ for (PersonalAttribute el : target)
+ updatedList.add(el);
+
+ Logger.debug("Updating " + source.size() + " attributes...");
+ for (PersonalAttribute current : source) {
+ Logger.debug("treating " + current.getName());
+
+ // check if we need to update the current pa
+ if (updatedList.containsKey(current.getName())) {
+ PersonalAttribute existing = target.get(current.getName());
+ if(!(existing.isEmptyValue() && existing.isEmptyComplexValue()))
+ if(!(existing.getValue().equals(current.getValue()) || existing.getComplexValue().equals(current.getComplexValue()))) {
+ Logger.error("Attribute Value does not match the value from first authentication!");
+ throw new MOAIDException("stork.16", new Object[] {existing.getName()});
+ }
+
+ updatedList.get(current.getName()).setStatus(current.getStatus());
+ updatedList.get(current.getName()).setValue(current.getValue());
+ updatedList.get(current.getName()).setComplexValue(current.getComplexValue());
+ } else
+ updatedList.add(current);
+
+ Logger.debug("...successfully treated " + current.getName());
+ }
+
+ return updatedList;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ // this action does not need any authentication. The authentication is already done by the preceding AuthenticationRequest-Action.
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ public String getDefaultActionName() {
+ return STORKProtocol.ATTRIBUTE_COLLECTOR;
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java
new file mode 100644
index 000000000..aadbbd959
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.commons.MOAIDConstants;
+import at.gv.egovernment.moa.id.config.stork.StorkAttributeProviderPlugin;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.EHvdAttributeProviderPlugin;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.MandateAttributeRequestProvider;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.PVPAuthenticationProvider;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.SignedDocAttributeRequestProvider;
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.StorkAttributeRequestProvider;
+import at.gv.egovernment.moa.logging.Logger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.PriorityQueue;
+
+/**
+ * A factory for creating AttributeProvider objects.
+ */
+public class AttributeProviderFactory {
+
+ /**
+ * Gets the available plugins.
+ *
+ * @return the available plugins
+ */
+ public static List<String> getAvailablePlugins() {
+ return MOAIDConstants.ALLOWED_STORKATTRIBUTEPROVIDERS;
+ }
+
+ /**
+ * Creates an AttributeProvider object for the given shortname. Returns
+ * {@code null} if there is no such provider available.
+ *
+ * @param shortname the simpleName for the providers class
+ * @return the attribute provider
+ */
+ public static AttributeProvider create(String shortname, String url, String attributes) {
+ if (shortname.equals("StorkAttributeRequestProvider")) {
+ return new StorkAttributeRequestProvider(url, attributes);
+ } else if (shortname.equals("EHvdAttributeProvider")) {
+ return new EHvdAttributeProviderPlugin(url, attributes);
+ } else if (shortname.equals("SignedDocAttributeRequestProvider")) {
+ return new SignedDocAttributeRequestProvider(url, attributes);
+ } else if (shortname.equals("MandateAttributeRequestProvider")) {
+ try {
+ return new MandateAttributeRequestProvider(url, attributes);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ } else if (shortname.equals("PVPAuthenticationProvider")) {
+ return new PVPAuthenticationProvider(url, attributes);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets fresh instances of the configured plugins.
+ *
+ * @param collection the configured a ps
+ * @return the configured plugins
+ */
+ public static Iterator<AttributeProvider> getConfiguredPlugins(
+ Collection<StorkAttributeProviderPlugin> collection) {
+
+ PriorityQueue<AttributeProvider> result = new PriorityQueue<AttributeProvider>();
+ for (StorkAttributeProviderPlugin current : collection) {
+
+ result.add(create(current.getName(), current.getUrl(), current.getAttributes()));
+ Logger.debug("Adding configured attribute provider: " + current.getClass().getName() + current.getName() + " at " + current.getUrl());
+ }
+
+ return result.iterator();
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java
new file mode 100644
index 000000000..59db5797d
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java
@@ -0,0 +1,531 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationImpl;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.id.util.client.mis.simple.MISMandate;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.stork.peps.auth.commons.*;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+
+/**
+ * Second request step - after authentication of the user is done and moasession obtained,
+ * process request and forward the user further to PEPS and/or other entities
+ *
+ * @author bsuzic
+ */
+
+public class AuthenticationRequest implements IAction {
+
+
+ private VelocityEngine velocityEngine;
+ private MOASTORKRequest moaStorkRequest = null;
+
+
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
+
+ if ((req instanceof MOASTORKRequest)) { // && ( ((MOASTORKRequest) req).getCitizenCountryCode() == null || ((MOASTORKRequest) req).getCitizenCountryCode().equals("AT") )) {
+
+ this.moaStorkRequest = (MOASTORKRequest) req;
+
+ Logger.debug("Entering MOASTORKRequest");
+ httpResp.reset();
+
+ //TODO: CHECK: req.getOAURL() should return the unique OA identifier
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(req.getOAURL());
+ if (oaParam == null)
+ throw new AuthenticationException("stork.12", new Object[]{req.getOAURL()});
+
+ MOASTORKResponse moaStorkResponse = new MOASTORKResponse();
+
+ // check if it is attribute query
+ if (moaStorkRequest.isAttrRequest()) {
+ Logger.debug("Starting AttrQueryRequest");
+
+ moaStorkResponse.setSTORKAttrResponse(new STORKAttrQueryResponse());
+ }
+ // check if we have authentication request
+ else if (moaStorkRequest.isAuthnRequest()) {
+ Logger.debug("Starting AuthenticationRequest");
+ moaStorkResponse.setSTORKAuthnResponse(new STORKAuthnResponse());
+
+ //STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+
+ // Logger.debug("Starting generation of SAML response");
+ // try {
+ // moaStorkResponse.setSTORKAuthnResponse(engine.generateSTORKAuthnResponse(moaStorkRequest.getStorkAuthnRequest(), moaStorkResponse.getStorkAuthnResponse(), httpReq.getRemoteAddr(), false));
+ // } catch (STORKSAMLEngineException ex) {
+ // Logger.error("Failed to generate STORK SAML Response", ex);
+ // throw new MOAIDException("stork.05", null); // TODO
+ // }
+
+ // Get personal attributtes from MOA/IdentityLink
+
+ //build STORK attributes from local authentication information
+ if (authData != null) {
+ int reqQaa = -1;
+ int authQaa = -1;
+ try {
+ reqQaa = moaStorkRequest.getStorkAuthnRequest().getQaa();
+ authQaa = Integer.valueOf(
+ authData.getQAALevel().substring(PVPConstants.STORK_QAA_PREFIX.length()));
+
+ if (reqQaa > authQaa) {
+ Logger.warn("Requested QAA level does not match to authenticated QAA level");
+ throw new MOAIDException("stork.21", new Object[]{reqQaa, authQaa});
+
+ }
+
+ } catch (MOAIDException e) {
+ throw e;
+
+ } catch (Exception e) {
+ if (Logger.isDebugEnabled())
+ Logger.warn("STORK QAA Level evaluation error", e);
+
+ else
+ Logger.warn("STORK QAA Level evaluation error (ErrorMessage="
+ + e.getMessage() + ")");
+
+ throw new MOAIDException("stork.21", new Object[]{reqQaa, authQaa});
+
+ }
+
+ moaStorkResponse.setPersonalAttributeList(populateAttributes(authData, oaParam));
+
+ }
+ }
+
+ //moaStorkResponse.setCountry(moaStorkRequest.getSpCountry());
+
+ // Prepare extended attributes
+ Logger.debug("Preparing data container");
+
+ // create fresh container
+ DataContainer container = new DataContainer();
+
+ // - fill in the request we extracted above
+ container.setRequest(moaStorkRequest);
+
+ // - fill in the partial response created above
+ container.setResponse(moaStorkResponse);
+
+ container.setRemoteAddress(httpReq.getRemoteAddr());
+
+ Logger.debug("Data container prepared");
+
+ if(oaParam.isRequireConsentForStorkAttributes())
+ new ConsentEvaluator().requestConsent(container, httpReq, httpResp, authData, oaParam);
+ else
+ new AttributeCollector().processRequest(container, httpReq, httpResp, authData, oaParam);
+
+ return null;
+ }
+// // check if we are getting request for citizen of some other country
+// else if (req instanceof MOASTORKRequest) {
+// return handleMOAStorkRequest("VIDP", (MOASTORKRequest) req, httpReq.getRemoteAddr(), httpResp);
+// }
+
+ // Check if we got the response from PEPS
+ // If so then process it and forward to SP
+ else if ((req instanceof MOASTORKResponse)) {
+ return handleMOAStorkResponse("VIDP", (MOASTORKResponse) req, httpReq.getRemoteAddr(), httpResp);
+ } else {
+ Logger.error("Could not recognize request.");
+ throw new MOAIDException("stork.15", null);
+ }
+ }
+
+ /*
+ Handles STORKAuthnRequeste received for citizens of other countries
+ */
+ private SLOInformationInterface handleMOAStorkRequest(String instanceName, MOASTORKRequest moastorkRequest, String remoteAddr, HttpServletResponse httpResp) throws MOAIDException {
+
+ STORKAuthnRequest spAuthnRequest = moastorkRequest.getStorkAuthnRequest();
+ STORKAuthnRequest storkAuthnRequest = null;
+
+ String citizenCountryCode = spAuthnRequest.getCitizenCountryCode();
+ Logger.info("Got authentication request for citizen of " + citizenCountryCode);
+
+ try {
+ storkAuthnRequest = (STORKAuthnRequest) spAuthnRequest.clone();
+ } catch (CloneNotSupportedException e) {
+ Logger.error("Could not clone AuthnRequest ", e);
+ throw new MOAIDException("stork.05", null); // TODO
+ }
+
+ //TODO: in case of Single LogOut -> SLO information has to be stored
+ // check if citizen country is configured in the system
+ if (!(AuthConfigurationProviderFactory.getInstance().getStorkConfig().getCpepsMap().containsKey(citizenCountryCode))) {
+ Logger.error("Citizen country PEPS not configured in MOA instance: " + citizenCountryCode);
+ throw new MOAIDException("stork.05", null); // TODO
+ }
+
+ // extracting basic settings and adjusting assertion consumer
+ String issuer = null;
+ String assertionConsumerURL = null;
+ String publicURLPrefix = null;
+ String destinationURL = null;
+
+ try {
+ issuer = new URL(AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix()).toString();
+ destinationURL = AuthConfigurationProviderFactory.getInstance().getStorkConfig().getCPEPS(citizenCountryCode).getPepsURL().toString();
+ publicURLPrefix = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix();
+ assertionConsumerURL = publicURLPrefix + "/stork2/SendPEPSAuthnRequest";
+ } catch (MalformedURLException ex) {
+ Logger.error("Wrong PublicURLPrefix setting of MOA instance: " + AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix(), ex);
+ throw new MOAIDException("stork.05", null); // TODO
+ } catch (Exception ex) {
+ Logger.error("Problem with PEPS configuration of MOA instance.", ex);
+ throw new MOAIDException("stork.05", null); // TODO
+ }
+
+
+ // drop if we do not have publicprefix url configured on the instance
+ if (publicURLPrefix == null)
+ throw new AuthenticationException("stork.12", new String[]{"PublicURLPrefix"});
+
+ // adjusting request
+ storkAuthnRequest.setEIDCrossBorderShare(spAuthnRequest.isEIDCrossBorderShare());
+ storkAuthnRequest.setEIDSectorShare(spAuthnRequest.isEIDSectorShare());
+ storkAuthnRequest.setEIDCrossSectorShare(spAuthnRequest.isEIDCrossSectorShare());
+ storkAuthnRequest.setCitizenCountryCode(spAuthnRequest.getCitizenCountryCode());
+ storkAuthnRequest.setIssuer(issuer);
+ storkAuthnRequest.setAssertionConsumerServiceURL(assertionConsumerURL);
+ storkAuthnRequest.setDestination(destinationURL);
+
+ // regenerate request
+ try {
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+ Logger.debug("Starting generation of SAML request");
+ storkAuthnRequest = engine.generateSTORKAuthnRequest(storkAuthnRequest);
+
+ //generateSAML Token
+ Logger.info("SAML response succesfully generated!");
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Failed to generate STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ // store original request from SP in order to be able to extract it in later iteration/response
+ DataContainer spRequestContainer = new DataContainer();
+ spRequestContainer.setRequest(moastorkRequest);
+
+ try {
+ AssertionStorage.getInstance().put(storkAuthnRequest.getSamlId(), spRequestContainer);
+ Logger.info("Storing artifactId " + storkAuthnRequest.getSamlId() + " of SP authentication request with id " + spAuthnRequest.getSamlId());
+ } catch (MOADatabaseException e) {
+ e.printStackTrace();
+ }
+
+ // preparing redirection for the client
+ performRedirection("SAMLRequest", destinationURL, storkAuthnRequest.getTokenSaml(), httpResp);
+
+ SLOInformationImpl sloInfo = new SLOInformationImpl();
+ sloInfo.setProtocolType(moastorkRequest.requestedModule());
+ return sloInfo;
+ }
+
+ /*
+ Handles STORKAuthnResponse received from PEPS (return to SP)
+ */
+ private SLOInformationInterface handleMOAStorkResponse(String instanceName, MOASTORKResponse moastorkResponse, String remoteAddr, HttpServletResponse httpResp) throws MOAIDException {
+
+ STORKAuthnResponse authnResponse = null;
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance(instanceName);
+
+ try {
+ authnResponse = engine.validateSTORKAuthnResponse(moastorkResponse.getSTORKAuthnResponseToken(), remoteAddr);
+ } catch (STORKSAMLEngineException ex) {
+ Logger.error("Unable to validate Stork AuthenticationResponse: " + ex.getMessage());
+ throw new MOAIDException("stork.15", null); // TODO
+ }
+
+ Logger.debug("Requesting artifactId " + authnResponse.getInResponseTo() + " from store.");
+
+ DataContainer dataContainer = null;
+ try {
+ dataContainer = AssertionStorage.getInstance().get(authnResponse.getInResponseTo(), DataContainer.class);
+ } catch (MOADatabaseException e) {
+ Logger.error("Unable to retrieve datacontainer with reference authentication request. Database exception.");
+ throw new MOAIDException("stork.15", null); // TODO
+ }
+
+ // setting new reference request and return url
+ authnResponse.setInResponseTo(dataContainer.getRequest().getStorkAuthnRequest().getSamlId());
+ authnResponse.setAudienceRestriction(dataContainer.getRequest().getAssertionConsumerServiceURL());
+ //AudienceRestrictionBuilder audienceRestrictionBuilder = new AudienceRestrictionBuilder();
+ //AudienceRestriction audienceRestriction = audienceRestrictionBuilder.buildObject(dataContainer.getRequest().getAssertionConsumerServiceURL(), "localname", "nameprefix");
+
+ //authnResponse.getAssertions().get(0).getConditions().getAudienceRestrictions().add(audienceRestriction);
+
+ Logger.debug("Starting generation of SAML response");
+ try {
+ authnResponse = engine.generateSTORKAuthnResponse(dataContainer.getRequest().getStorkAuthnRequest(), authnResponse, remoteAddr, false);
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Failed to generate STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null); // TODO check
+ }
+
+ Logger.info("SAML response succesfully generated.");
+
+ // preparing redirection for the client
+ performRedirection("SAMLResponse", dataContainer.getRequest().getAssertionConsumerServiceURL(), authnResponse.getTokenSaml(), httpResp);
+
+ return null;
+ }
+
+ /*
+ Perform redirection of the client based on post binding
+ */
+ private void performRedirection(String actionType, String assertionConsumerURL, byte[] tokenSaml, HttpServletResponse httpResp) throws MOAIDException {
+ Logger.info("Performing redirection, using action type: " + actionType);
+
+ try {
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html");
+ VelocityContext context = new VelocityContext();
+
+ context.put(actionType, PEPSUtil.encodeSAMLToken(tokenSaml));
+ Logger.debug("Encoded " + actionType + " original: " + new String(tokenSaml));
+
+ Logger.debug("Using assertion consumer url as action: " + assertionConsumerURL);
+ context.put("action", assertionConsumerURL);
+
+ Logger.debug("Starting template merge");
+ StringWriter writer = new StringWriter();
+
+ Logger.debug("Doing template merge");
+ template.merge(context, writer);
+ Logger.debug("Template merge done");
+
+ Logger.debug("Sending html content: " + writer.getBuffer().toString());
+ Logger.debug("Sending html content2 : " + new String(writer.getBuffer()));
+
+ httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8"));
+
+ } catch (IOException e) {
+ Logger.error("Velocity IO error: " + e.getMessage());
+ throw new MOAIDException("stork.15", null); // TODO
+ } catch (Exception e) {
+ Logger.error("Velocity general error: " + e.getMessage());
+ throw new MOAIDException("stork.15", null); // TODO
+ }
+
+ }
+
+ public void generatePEPSRedirect(HttpServletResponse httpResp, DataContainer container) throws MOAIDException {
+ MOASTORKRequest request = container.getRequest();
+ MOASTORKResponse response = container.getResponse();
+
+ Logger.info("generating stork response...");
+
+ try {
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+ Logger.debug("Starting generation of SAML response");
+ if (response.isAuthnResponse())
+ response.setSTORKAuthnResponse(engine.generateSTORKAuthnResponse(request.getStorkAuthnRequest(), response.getStorkAuthnResponse(), container.getRemoteAddress(), false));
+ else
+ response.setSTORKAttrResponse(engine.generateSTORKAttrQueryResponse(request.getStorkAttrQueryRequest(), response.getStorkAttrQueryResponse(), container.getRemoteAddress(), "", false));
+
+
+ //generateSAML Token
+ Logger.info("SAML response succesfully generated!");
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Failed to generate STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ // preparing redirection for the client
+ try {
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html");
+ VelocityContext context = new VelocityContext();
+
+ byte[] blob;
+ if (request.isAttrRequest())
+ blob = response.getStorkAttrQueryResponse().getTokenSaml();
+ else
+ blob = response.getStorkAuthnResponse().getTokenSaml();
+
+ context.put("SAMLResponse", PEPSUtil.encodeSAMLToken(blob));
+ Logger.debug("SAMLResponse original: " + new String(blob));
+
+ Logger.debug("Putting assertion consumer url as action: " + request.getAssertionConsumerServiceURL());
+ context.put("action", request.getAssertionConsumerServiceURL());
+ Logger.trace("Starting template merge");
+ StringWriter writer = new StringWriter();
+
+ Logger.trace("Doing template merge");
+ template.merge(context, writer);
+ Logger.trace("Template merge done");
+
+ Logger.trace("Sending html content: " + writer.getBuffer().toString());
+ Logger.trace("Sending html content2 : " + new String(writer.getBuffer()));
+
+ httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8"));
+
+ } catch (Exception e) {
+ Logger.error("Velocity error: " + e.getMessage());
+ }
+ }
+
+
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+
+ //redirect to national PVP IDP infrastructure if special attributes are requested
+ if (MiscUtil.isEmpty(req.getRequestedIDP()) && req instanceof MOASTORKRequest)
+ return !STORKPVPUtilits.performAuthenticationOnNationalIDP((MOASTORKRequest) req);
+
+// // authentication is not needed if we have authentication request from SP for citizen of configured PEPS country
+// if (req instanceof MOASTORKRequest) {
+// MOASTORKRequest moastorkRequest = (MOASTORKRequest) req;
+// if (moastorkRequest.getStorkAuthnRequest() != null) {
+// String citizenCountryCode = moastorkRequest.getStorkAuthnRequest().getCitizenCountryCode();
+// // check if citizen country is configured in the system
+// try {
+// if (AuthConfigurationProvider.getInstance().getStorkConfig().getCpepsMap().containsKey(citizenCountryCode)) {
+// return false;
+// }
+// } catch (MOAIDException e) {
+// Logger.error("Could not initialize AuthConfigurationProvider");
+// }
+// }
+// // authentication is not required if received authentication response
+// } else if (req instanceof MOASTORKResponse) {
+// return false;
+// }
+
+ return true;
+ }
+
+
+ private void iterate(NamedNodeMap attributesList) {
+ for (int j = 0; j < attributesList.getLength(); j++) {
+ Logger.debug("--Attribute: "
+ + attributesList.item(j).getNodeName() + " = "
+ + attributesList.item(j).getNodeValue());
+ }
+ }
+
+
+ // does nothing
+ public void mandate(IAuthData authData) {
+
+ if (authData.isUseMandate()) {
+ try {
+ MISMandate mandate = authData.getMISMandate();
+ String owbpk = mandate.getOWbPK();
+ byte[] mand = mandate.getMandate();
+ String profprep = mandate.getProfRep();
+ //String textdesc = mandate.getTextualDescriptionOfOID();
+ Element mndt = authData.getMandate();
+
+ iterate(mndt.getAttributes());
+ Logger.debug("mandate encoded: " + new String(org.bouncycastle.util.encoders.Base64.encode(mand)));
+ } catch (Exception x) {
+ Logger.debug("There is no mandate used in transaction");
+ }
+ }
+
+
+ }
+
+ public PersonalAttributeList populateAttributes(IAuthData authData, IOAAuthParameters oaParam) {
+
+ IPersonalAttributeList attrLst = moaStorkRequest.getStorkAuthnRequest().getPersonalAttributeList();
+ Logger.info("Found " + attrLst.size() + " personal attributes in the request.");
+
+ // Define attribute list to be populated
+ PersonalAttributeList attributeList = new PersonalAttributeList();
+ MOAAttributeProvider moaAttributeProvider = new MOAAttributeProvider(authData, moaStorkRequest);
+
+ try {
+ for (PersonalAttribute personalAttribute : attrLst) {
+ try {
+ Logger.debug("Personal attribute found in request: " + personalAttribute.getName() + " isRequired: " + personalAttribute.isRequired());
+ moaAttributeProvider.populateAttribute(attributeList, personalAttribute);
+ } catch (Exception e) {
+ Logger.error("Exception, attributes: " + e.getMessage(), e);
+ }
+ }
+ } catch (Exception e) {
+ Logger.error("Exception, attributes: " + e.getMessage(), e);
+ }
+
+ Logger.trace("AUTHBLOCK " + authData.getAuthBlock());
+ Logger.debug("SESSION IDENTIFIER " + authData.getCcc() + " " + oaParam.getIdentityLinkDomainIdentifier());
+
+ return attributeList;
+ }
+
+ public String getDefaultActionName() {
+ return STORKProtocol.AUTHENTICATIONREQUEST;
+ }
+
+
+ private void initVelocityEngine() throws Exception {
+ velocityEngine = new VelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8");
+ velocityEngine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
+ velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+ velocityEngine.setProperty("classpath.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+
+ velocityEngine.init();
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java
new file mode 100644
index 000000000..bde0f362d
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import java.io.StringWriter;
+
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The ConsentEvaluator assists with fetching user consent on the list of attributes to be sent to the asking S-PEPS.
+ */
+public class ConsentEvaluator implements IAction {
+
+ /**
+ * The Constant ARTIFACT_ID.
+ */
+ private static final String ARTIFACT_ID = "artifactId";
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.auth.data.AuthenticationSession)
+ */
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
+
+ // - fetch the container
+ String artifactId = (String) httpReq.getParameter(ARTIFACT_ID);
+ DataContainer container;
+ try {
+ container = AssertionStorage.getInstance().get(artifactId, DataContainer.class);
+ req = container.getRequest();
+ } catch (MOADatabaseException e) {
+ Logger.error("Error fetching incomplete Stork response from temporary storage. Most likely a timeout occured.", e);
+ throw new MOAIDException("stork.17", null);
+ }
+
+ // evaluate response
+ for(PersonalAttribute current : container.getRequest().getPersonalAttributeList()) {
+ if(null == httpReq.getParameter(current.getName())) {
+ current.setStatus(AttributeStatusType.WITHHELD.value());
+ current.setValue(new ArrayList<String>());
+ current.setComplexValue(new HashMap<String, String>());
+ }
+ }
+
+ //TODO: CHECK: req.getOAURL() should return the unique OA identifier
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(req.getOAURL());
+ if (oaParam == null)
+ throw new AuthenticationException("stork.12", new Object[]{req.getOAURL()});
+
+ new AttributeCollector().processRequest(container, httpReq, httpResp, authData, oaParam);
+
+ return null; // AssertionId
+ }
+
+ /**
+ * Fills the given HttpResponse with the required web page.
+ *
+ * @param container the container
+ * @param authData
+ * @param response the response
+ * @param oaParam the oa param
+ * @return the string
+ * @throws MOAIDException the mOAID exception
+ */
+ public String requestConsent(DataContainer container, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData, OAAuthParameter oaParam) throws MOAIDException {
+ //check if we need to collect consent
+ if(!oaParam.isRequireConsentForStorkAttributes()) {
+ (new AttributeCollector()).processRequest(container, httpReq, httpResp, authData, oaParam);
+ return "";
+ }
+
+ // prepare redirect
+ String newArtifactId;
+ try {
+
+ // memorize the container again
+ Logger.debug("prepare putting the container into temporary storage...");
+
+ // - generate new key
+ newArtifactId = new SecureRandomIdentifierGenerator().generateIdentifier();
+
+ // - put container in temporary store.
+ AssertionStorage.getInstance().put(newArtifactId, container);
+
+ Logger.debug("...successful");
+
+ } catch (Exception e1) {
+ // TODO should we return the response as is to the PEPS?
+ e1.printStackTrace();
+ Logger.error("Error putting incomplete Stork response into temporary storage", e1);
+ throw new MOAIDException("stork.17", null);
+ }
+
+ // ask for consent
+ try {
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/stork2_consent.html");
+ VelocityContext context = new VelocityContext();
+
+ context.put("action", AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix() + "/stork2/CompleteAuthentication?" + ARTIFACT_ID + "=" + newArtifactId);
+
+ // assemble table
+ String table = "";
+ for (PersonalAttribute current : container.getRequest().getPersonalAttributeList())
+ table += "<tr><td><input type=\"checkbox\" checked=\"yes\" name=\"" + current.getName() + "\"></td><td>" + current.getName() + (current.isRequired() ? "" : " (optional)") + "</td></tr>\n";
+
+ context.put("tablecontent", table);
+ for(Entry<String, String> current : oaParam.getFormCustomizaten().entrySet())
+ context.put(current.getKey().replace("#", ""), current.getValue());
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+ httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8"));
+
+ } catch (Exception e) {
+ Logger.error("Velocity error: " + e.getMessage());
+ throw new MOAIDException("stork.17", null);
+ }
+
+ return "12345"; // AssertionId
+ }
+
+ /**
+ * generates binary response from given response class and fill the given HttpResponse with a SAML Post Binding template.
+ *
+ * @param httpResp the http resp
+ * @param container the container
+ * @throws MOAIDException the mOAID exception
+ */
+ public void generateSTORKResponse(HttpServletResponse httpResp, DataContainer container) throws MOAIDException {
+ MOASTORKRequest request = container.getRequest();
+ MOASTORKResponse response = container.getResponse();
+
+ Logger.info("generating stork response...");
+
+ try {
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+ Logger.debug("Starting generation of SAML response");
+ if(response.isAuthnResponse())
+ response.setSTORKAuthnResponse(engine.generateSTORKAuthnResponse(request.getStorkAuthnRequest(), response.getStorkAuthnResponse(), container.getRemoteAddress(), false));
+ else
+ response.setSTORKAttrResponse(engine.generateSTORKAttrQueryResponse(request.getStorkAttrQueryRequest(), response.getStorkAttrQueryResponse(), container.getRemoteAddress(), "", false));
+
+
+ //generateSAML Token
+ Logger.info("SAML response succesfully generated!");
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Failed to generate STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ // preparing redirection for the client
+ try {
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html");
+ VelocityContext context = new VelocityContext();
+
+ byte[] blob;
+ if(request.isAttrRequest())
+ blob = response.getStorkAttrQueryResponse().getTokenSaml();
+ else
+ blob = response.getStorkAuthnResponse().getTokenSaml();
+
+ context.put("SAMLResponse", PEPSUtil.encodeSAMLToken(blob));
+ Logger.debug("SAMLResponse original: " + new String(blob));
+
+ Logger.debug("Putting assertion consumer url as action: " + request.getAssertionConsumerServiceURL());
+ context.put("action", request.getAssertionConsumerServiceURL());
+ Logger.trace("Starting template merge");
+ StringWriter writer = new StringWriter();
+
+ Logger.trace("Doing template merge");
+ template.merge(context, writer);
+ Logger.trace("Template merge done");
+
+ Logger.trace("Sending html content: " + writer.getBuffer().toString());
+ Logger.trace("Sending html content2 : " + new String(writer.getBuffer()));
+
+ httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8"));
+
+ } catch (Exception e) {
+ Logger.error("Velocity error: " + e.getMessage());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ // this action does not need any authentication. The authentication is already done by the preceding AuthenticationRequest-Action.
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ public String getDefaultActionName() {
+ return STORKProtocol.CONSENT_EVALUATOR;
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/CorporateBodyMandateContainer.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/CorporateBodyMandateContainer.java
new file mode 100644
index 000000000..acbf1678a
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/CorporateBodyMandateContainer.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.logging.Logger;
+import org.xml.sax.InputSource;
+
+import javax.xml.xpath.XPathExpressionException;
+import java.io.StringReader;
+/**
+ * Physical person representing corporate body
+ *
+ * @author bsuzic
+ * Date: 4/29/14, Time: 3:40 PM
+ */
+public class CorporateBodyMandateContainer extends MandateContainer {
+
+ protected String corpMandatorIdentificationValue = null;
+ protected String corpMandatorIdentificationType = null;
+ protected String corpMandatorFullName = null;
+
+
+ String localMethods[] = new String[]{"getCorpMandatorIdentificationValue", "getCorpMandatorIdentificationType", "getCorpMandatorFullName",
+ "getMandateIssuePlace", "getMandateIssueDate", "getMandateIssueTime", "getSimpleMandateContent", "getMandateValidFrom",
+ "getMandateValidTo", "getPhysicalRepresentativeIdentificationValue", "getPhysicalRepresentativeIdentificationType", "getAnnotation",
+ "getPhysicalRepresentativeGivenName", "getPhysicalRepresentativeFamilyName", "getPhysicalRepresentativeBirthDate"
+ };
+
+ public CorporateBodyMandateContainer(String mandate) throws XPathExpressionException, MOAIDException {
+ super(mandate);
+ Logger.debug("Initializing corporate body mandate container.");
+
+ setAnnotation(xPath.evaluate(S2Constants.MANDATE_ANNOTATION_QUERY, new InputSource(new StringReader(mandate))));
+ setCorpMandatorFullName(xPath.evaluate(S2Constants.MANDATE_MANDATOR_CORPBODY_FULLNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setCorpMandatorIdentificationType(xPath.evaluate(S2Constants.MANDATE_MANDATOR_CORPBODY_IDTYPE_QUERY, new InputSource(new StringReader(mandate))));
+ setCorpMandatorIdentificationValue(xPath.evaluate(S2Constants.MANDATE_MANDATOR_CORPBODY_IDVALUE_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateIssueDate(xPath.evaluate(S2Constants.MANDATE_ISSUEDDATE_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateIssuePlace(xPath.evaluate(S2Constants.MANDATE_ISSUEDPLACE_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateIssueTime(xPath.evaluate(S2Constants.MANDATE_ISSUEDTIME_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateValidFrom(xPath.evaluate(S2Constants.MANDATE_SIMPLEMANDATECONTENT_VALIDFROM_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateValidTo(xPath.evaluate(S2Constants.MANDATE_SIMPLEMANDATECONTENT_VALIDTO_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeBirthDate(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_DATEOFBIRTH_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeFamilyName(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_FAMILYNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeGivenName(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_GIVENNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeIdentificationType(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_IDTYPE_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeIdentificationValue(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_IDVALUE_QUERY, new InputSource(new StringReader(mandate))));
+ setSimpleMandateContent(xPath.evaluate(S2Constants.MANDATE_SIMPLEMANDATECONTENT_TXTDESC_QUERY, new InputSource(new StringReader(mandate))));
+
+ // check if all necessary fields are present
+ Logger.debug("Starting mandate structure validation");
+ try {
+ validateMandateStructure(localMethods); // TODO
+ } catch (Exception e) {
+
+ if (e instanceof MOAIDException) {
+ Logger.error("Could not validate mandate structure.");
+ throw new MOAIDException("stork.16", new Object[] {e.getMessage()}); // TODO
+ } else {
+ Logger.error("Error during mandate structure validation.");
+ throw new MOAIDException("stork.16", new Object[] {e.getMessage()}); // TODO
+ }
+
+ }
+
+ }
+
+ public String getCorpMandatorIdentificationValue() {
+ return corpMandatorIdentificationValue;
+ }
+
+ public void setCorpMandatorIdentificationValue(String corpMandatorIdentificationValue) {
+ Logger.debug("Setting corpMandatorIdentificationValue to AT/" + corpMandatorIdentificationValue);
+ this.corpMandatorIdentificationValue = "AT/" + corpMandatorIdentificationValue;
+ }
+
+ public String getCorpMandatorIdentificationType() {
+ return corpMandatorIdentificationType;
+ }
+
+ public void setCorpMandatorIdentificationType(String corpMandatorIdentificationType) {
+ this.corpMandatorIdentificationType = corpMandatorIdentificationType;
+ }
+
+ public String getCorpMandatorFullName() {
+ return corpMandatorFullName;
+ }
+
+ public void setCorpMandatorFullName(String corpMandatorFullName) {
+ this.corpMandatorFullName = corpMandatorFullName;
+ }
+
+
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java
new file mode 100644
index 000000000..e01a7526a
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import java.io.Serializable;
+
+/**
+ * Holds info about an ongoing but yet incomplete stork authnrequest process.
+ */
+public class DataContainer implements Serializable {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = -8765997480582363012L;
+
+ /** The incoming request. */
+ private MOASTORKRequest request;
+
+ /** The yet incomplete response. */
+ private MOASTORKResponse response;
+
+ /** The target. */
+ private String target;
+
+ /** The remote address. */
+ private String remoteAddress;
+
+ /**
+ * Gets the request.
+ *
+ * @return the request
+ */
+ public MOASTORKRequest getRequest() {
+ return request;
+ }
+
+ /**
+ * Sets the request.
+ *
+ * @param moaStorkRequest the new request
+ */
+ public void setRequest(MOASTORKRequest moaStorkRequest) {
+ this.request = moaStorkRequest;
+ }
+
+ /**
+ * Gets the response.
+ *
+ * @return the response
+ */
+ public MOASTORKResponse getResponse() {
+ return response;
+ }
+
+ /**
+ * Sets the response.
+ *
+ * @param moaStorkResponse the new response
+ */
+ public void setResponse(MOASTORKResponse moaStorkResponse) {
+ this.response = moaStorkResponse;
+ }
+
+ /**
+ * Gets the remote address.
+ *
+ * @return the remote address
+ */
+ public String getRemoteAddress() {
+ return remoteAddress;
+ }
+
+ /**
+ * Sets the remote address.
+ *
+ * @param remoteAddress the new remote address
+ */
+ public void setRemoteAddress(String remoteAddress) {
+ this.remoteAddress = remoteAddress;
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java
new file mode 100644
index 000000000..096f223d7
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider;
+
+public class ExternalAttributeRequestRequiredException extends Exception {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 5207631348933518908L;
+
+ /** The ap. */
+ private AttributeProvider ap;
+
+ /**
+ * Instantiates a new external attribute request required exception.
+ *
+ * @param provider the provider
+ */
+ public ExternalAttributeRequestRequiredException(AttributeProvider provider) {
+ ap = provider;
+ }
+
+ /**
+ * Gets the ap that caused the exception.
+ *
+ * @return the ap
+ */
+ public AttributeProvider getAp() {
+ return ap;
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java
new file mode 100644
index 000000000..2c7e5b539
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.exception.BuildException;
+import at.gv.egovernment.moa.id.data.AuthenticationRole;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.util.PVPtoSTORKMapper;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType;
+import org.joda.time.Period;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author bsuzic
+ * Date: 2/19/14, Time: 4:42 PM
+ *
+ * @author tlenz
+ * Date: 23.10.14
+ */
+public class MOAAttributeProvider {
+ private final IAuthData authData;
+ private static final Map<String, String> storkAttributeSimpleMapping;
+ private static final Map<String, String> storkAttributeFunctionMapping;
+ private final MOASTORKRequest moastorkRequest;
+
+ // mappings for attribute population methods
+ // based on mapping of moa authndata and executing functions to extract attributes
+ static {
+ Map<String, String> tempSimpleMap = new HashMap<String, String>();
+ tempSimpleMap.put("givenName", "getGivenName");
+ tempSimpleMap.put("surname", "getFamilyName");
+ tempSimpleMap.put("MSOrganization", "getPvpAttribute_OU");
+ storkAttributeSimpleMapping = Collections.unmodifiableMap(tempSimpleMap);
+
+ Map<String, String> tempFunctionMap = new HashMap<String, String>();
+ tempFunctionMap.put("eIdentifier", "geteIdentifier");
+ tempFunctionMap.put("ECApplicationRole","getECApplicationRole");
+ tempFunctionMap.put("dateOfBirth", "getFormatedDateOfBirth");
+ tempFunctionMap.put("MSOrganization", "getMSOrganization");
+ tempFunctionMap.put("age", "getAge");
+ tempFunctionMap.put("isAgeOver", "getIsAgeOver");
+ tempFunctionMap.put("citizenQAALevel", "getQAALevel");
+ storkAttributeFunctionMapping = Collections.unmodifiableMap(tempFunctionMap);
+
+ }
+
+ public MOAAttributeProvider(IAuthData authData, MOASTORKRequest moastorkRequest) {
+ this.authData = authData;
+ this.moastorkRequest = moastorkRequest;
+
+ }
+
+ public void populateAttribute(PersonalAttributeList attributeList, PersonalAttribute requestedAttribute ) {
+ String storkAttribute = requestedAttribute.getName();
+
+ // TODO: check if authData gets populated with stork attributtes during previous steps; it seems it is not
+ if (null != authData && null != authData.getStorkAttributes() && authData.getStorkAttributes().containsKey(requestedAttribute.getName())) {
+ Logger.debug("Trying to get value for attribute directly from STORK2 response [" + storkAttribute + "]");
+ try {
+ PersonalAttribute tmp = authData.getStorkAttributes().get(requestedAttribute.getName());
+ attributeList.add((PersonalAttribute) tmp.clone());
+ } catch(Exception e) {
+ Logger.error("Could not retrieve attribute from STORK2 response: " + storkAttribute);
+ Logger.debug(e);
+ }
+ } else if (storkAttributeSimpleMapping.containsKey(storkAttribute)) {
+ Logger.debug("Trying to get value for attribute using simple mapping [" + storkAttribute + "]");
+ try {
+ Method method = authData.getClass().getDeclaredMethod(storkAttributeSimpleMapping.get(storkAttribute));
+ populateAttributeWithMethod(method, authData, attributeList, storkAttribute, requestedAttribute);
+ } catch (NoSuchMethodException e) {
+ Logger.error("Could not found MOA extraction method while getting attribute: " + storkAttribute);
+ Logger.debug(e);
+ } catch (NullPointerException e) {
+ Logger.error("Error getting MOA extraction method while getting attribute: " + storkAttribute);
+ Logger.debug(e);
+ }
+
+ } else if (storkAttributeFunctionMapping.containsKey(storkAttribute)) {
+
+ Logger.debug("Trying to get value for attribute using function mapping [" + storkAttribute + "]");
+ try {
+ Method method = this.getClass().getDeclaredMethod(storkAttributeFunctionMapping.get(storkAttribute), PersonalAttribute.class);
+ populateAttributeWithMethod(method, this, attributeList, storkAttribute, requestedAttribute);
+ } catch (NoSuchMethodException e) {
+ Logger.error("Could not found MOA extraction method while getting attribute: " + storkAttribute);
+ }
+ } else {
+ Logger.debug("MOA method for extraction of attribute " + storkAttribute + " not defined.");
+ }
+ }
+
+ private String getAge(PersonalAttribute personalAttribute) {
+ if (authData.getDateOfBirth() != null) {
+ Integer age = new Period(authData.getDateOfBirth().getTime(), Calendar.getInstance().getTime().getTime()).getYears();
+ return age >= 0 ? age.toString() : null;
+ }
+ return null; // WP4 D4.2, Table 12:age, description - considerations
+ }
+
+ private String getIsAgeOver(PersonalAttribute personalAttribute)
+ {
+ try {
+ if ((authData.getDateOfBirth() != null) && (personalAttribute.getValue() != null) && (personalAttribute.getValue().size() > 0)) {
+ Integer ageOver = Integer.parseInt(personalAttribute.getValue().get(0));
+ Integer age = new Period(authData.getDateOfBirth().getTime(), Calendar.getInstance().getTime().getTime()).getYears();
+ return age >= ageOver ? ageOver.toString() : "";
+ }
+ } catch (Exception ex) {
+ Logger.error("Error encountered when determining isAgeOver");
+ Logger.debug(ex);
+ }
+ return null;
+ }
+
+ public String getQAALevel(PersonalAttribute personalAttribute) {
+ if (authData.getQAALevel().startsWith(PVPConstants.STORK_QAA_PREFIX))
+ return authData.getQAALevel().substring(PVPConstants.STORK_QAA_PREFIX.length());
+ else
+ return null;
+ }
+
+
+ private String geteIdentifier(PersonalAttribute personalAttribute) {
+ Logger.debug("Using base urn for identification value: " + authData.getIdentificationType() + " and target country: " + moastorkRequest.getStorkAuthnRequest().getSpCountry());
+ try {
+ return new BPKBuilder().buildStorkeIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(),
+ moastorkRequest.getStorkAuthnRequest().getSpCountry());
+ } catch (BuildException be) {
+ Logger.error("Stork eid could not be constructed; " + be.getMessage());
+ return null; // TODO error
+ }
+ }
+
+ private List<String> getECApplicationRole(PersonalAttribute personalAttribute) {
+ List<String> storkRoles = null;
+
+ if (authData.getAuthenticationRoles() != null
+ && authData.getAuthenticationRoles().size() > 0) {
+
+ storkRoles = new ArrayList<String>();
+ PVPtoSTORKMapper mapper = PVPtoSTORKMapper.getInstance();
+ for (AuthenticationRole el : authData.getAuthenticationRoles()) {
+ String storkRole = mapper.map(el);
+ if (MiscUtil.isNotEmpty(storkRole))
+ storkRoles.add(storkRole);
+ }
+ }
+ return storkRoles;
+ }
+
+ private String getFormatedDateOfBirth(PersonalAttribute personalAttribute) {
+ if (authData.getDateOfBirth() != null) {
+ DateFormat fmt = new SimpleDateFormat("yyyyMMdd");
+ return fmt.format(authData.getDateOfBirth());
+ }
+ else
+ return null;
+ }
+
+ private void populateAttributeWithMethod(Method method, Object object, PersonalAttributeList attributeList, String storkAttribute, PersonalAttribute requestedAttribute) {
+ try {
+ Object attributeValue;
+ if (storkAttributeSimpleMapping.containsValue(method.getName())) {
+ attributeValue = method.invoke(object, new Class[]{});
+ } else {
+ attributeValue = method.invoke(object, requestedAttribute);
+ }
+
+ PersonalAttribute newAttribute = new PersonalAttribute();
+ newAttribute.setName(storkAttribute);
+ newAttribute.setIsRequired(requestedAttribute.isRequired());
+
+ if (attributeValue != null) {
+ newAttribute.setStatus(AttributeStatusType.AVAILABLE.value());
+ Logger.info("Got attribute value: " + attributeValue);
+
+ if (attributeValue instanceof String)
+ newAttribute.setValue(new ArrayList<String>(Collections.singletonList((String)attributeValue)));
+
+ else if (attributeValue instanceof List<?>) {
+ List<?> attributeValueList = (List<?>) attributeValue;
+ if (attributeValueList.size() > 0 && attributeValueList.get(0) instanceof String) {
+ newAttribute.setValue((List<String>) attributeValueList);
+
+ } else {
+ Logger.info("Attribute " + storkAttribute + " is not available.");
+ newAttribute.setStatus(AttributeStatusType.NOT_AVAILABLE.value());
+
+ }
+
+ } else {
+ Logger.error("Receive an unsupported type for attribute " + storkAttribute);
+
+ }
+ attributeList.add(newAttribute);
+
+ } else {
+ Logger.info("Attribute " + storkAttribute + " is not available.");
+ newAttribute.setStatus(AttributeStatusType.NOT_AVAILABLE.value());
+ }
+
+ } catch (InvocationTargetException e) {
+ Logger.error("Invocation target exception while getting attribute: " + storkAttribute);
+ Logger.debug(e);
+ } catch (IllegalAccessException e) {
+ Logger.error("Illegal access exception while getting attribute: " + storkAttribute);
+ Logger.debug(e);
+ } catch (NullPointerException e) {
+ Logger.error("Could not find method: " + storkAttribute);
+ Logger.debug(e);
+ }
+ }
+
+
+}
+
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKRequest.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKRequest.java
new file mode 100644
index 000000000..11eb01453
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKRequest.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.opensaml.saml2.core.Attribute;
+
+import at.gv.egovernment.moa.id.auth.builder.DynamicOAAuthParameterBuilder;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.config.auth.data.DynamicOAAuthParameters;
+import at.gv.egovernment.moa.id.moduls.RequestImpl;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.commons.STORKAuthnRequest;
+import eu.stork.peps.auth.commons.STORKAuthnResponse;
+
+/**
+ * Implements MOA request and stores StorkAuthn/Attr-Request related data.
+ *
+ * @author bsuzic
+ */
+public class MOASTORKRequest extends RequestImpl {
+
+ public static final List<String> DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList(
+ new String[] {
+ PVPConstants.BPK_NAME,
+ PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME,
+ PVPConstants.GIVEN_NAME_NAME,
+ PVPConstants.PRINCIPAL_NAME_NAME,
+ PVPConstants.BIRTHDATE_NAME,
+ PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME,
+ });
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 4581953368724501376L;
+
+ /** The request id. */
+ private String requestID;
+
+ /** The stork authn request. */
+ private STORKAuthnRequest storkAuthnRequest;
+
+ /** The stork attr query request. */
+ private STORKAttrQueryRequest storkAttrQueryRequest;
+
+
+ /**
+ * Sets the sTORK authn request.
+ *
+ * @param request the new sTORK authn request
+ */
+ public void setSTORKAuthnRequest(STORKAuthnRequest request) {
+ this.storkAuthnRequest = request;
+ }
+
+ /**
+ * Sets the sTORK attr request.
+ *
+ * @param request the new sTORK attr request
+ */
+ public void setSTORKAttrRequest(STORKAttrQueryRequest request) {
+ this.storkAttrQueryRequest = request;
+ }
+
+ /**
+ * Checks if the container holds an AttrQueryRequest
+ *
+ * @return true, if is attr request
+ */
+ public boolean isAttrRequest() {
+ return null != storkAttrQueryRequest;
+ }
+
+ /**
+ * Checks if the container holds an AuthnRequest
+ *
+ * @return true, if is authn request
+ */
+ public boolean isAuthnRequest() {
+ return null != storkAuthnRequest;
+ }
+
+ /**
+ * Gets the stork authn request.
+ *
+ * @return the stork authn request
+ */
+ public STORKAuthnRequest getStorkAuthnRequest() {
+ return this.storkAuthnRequest;
+ }
+
+ /**
+ * Gets the stork attr query request.
+ *
+ * @return the stork attr query request
+ */
+ public STORKAttrQueryRequest getStorkAttrQueryRequest() {
+ return this.storkAttrQueryRequest;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#getOAURL()
+ */
+ public String getOAURL() {
+ if (isAuthnRequest())
+ return storkAuthnRequest.getAssertionConsumerServiceURL();
+ else if (isAttrRequest())
+ return storkAttrQueryRequest.getAssertionConsumerServiceURL();
+ else {
+ Logger.error("There is no authentication or attribute request contained in MOASTORKRequest.");
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#isPassiv()
+ */
+ public boolean isPassiv() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#forceAuth()
+ */
+ public boolean forceAuth() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#isSSOSupported()
+ */
+ public boolean isSSOSupported() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#setRequestID(java.lang.String)
+ */
+ public void setRequestID(String id) {
+ this.requestID = id;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#getRequestID()
+ */
+ public String getRequestID() {
+ return this.requestID;
+ }
+
+ /**
+ * Gets the personal attribute list.
+ *
+ * @return the personal attribute list
+ */
+ public IPersonalAttributeList getPersonalAttributeList() {
+ if(isAttrRequest())
+ return this.storkAttrQueryRequest.getPersonalAttributeList();
+ else
+ return this.storkAuthnRequest.getPersonalAttributeList();
+ }
+
+ /**
+ * Gets the sp country.
+ *
+ * @return the sp country
+ */
+ public String getSpCountry() {
+ if(isAttrRequest())
+ return this.storkAttrQueryRequest.getSpCountry();
+ else
+ return this.storkAuthnRequest.getSpCountry();
+ }
+
+ /**
+ * Gets the assertion consumer service url.
+ *
+ * @return the assertion consumer service url
+ */
+ public String getAssertionConsumerServiceURL() {
+ if(isAttrRequest())
+ return this.storkAttrQueryRequest.getAssertionConsumerServiceURL();
+ else
+ return this.storkAuthnRequest.getAssertionConsumerServiceURL();
+ }
+
+ /**
+ * Gets the citizen country code.
+ *
+ * @return the citizen country code
+ */
+ public String getCitizenCountryCode() {
+ if(isAttrRequest())
+ return this.storkAttrQueryRequest.getCitizenCountryCode();
+ else
+ return this.storkAuthnRequest.getCitizenCountryCode();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes()
+ */
+ @Override
+ public List<Attribute> getRequestedAttributes() {
+ //TODO: only for testing with MOA-ID as PVP Stammportal
+ IOAAuthParameters oa;
+ try {
+ oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(getOAURL());
+ oa = DynamicOAAuthParameterBuilder.buildFromAuthnRequest(oa, this);
+
+ DynamicOAAuthParameters tmp = (DynamicOAAuthParameters) oa;
+ tmp.setBusinessTarget(Constants.URN_PREFIX_CDID + "+BF");
+
+ return AttributQueryBuilder.buildSAML2AttributeList(tmp, DEFAULTREQUESTEDATTRFORINTERFEDERATION.iterator());
+
+ } catch (ConfigurationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ }
+
+ //return new ArrayList<Attribute>();
+
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKResponse.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKResponse.java
new file mode 100644
index 000000000..d2cf2e813
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOASTORKResponse.java
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.moduls.RequestImpl;
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
+import eu.stork.peps.auth.commons.STORKAuthnResponse;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.opensaml.saml2.core.Attribute;
+
+/**
+ * Implements MOA request and stores StorkAuthn/Attr-Request related data.
+ *
+ * @author bsuzic
+ */
+public class MOASTORKResponse extends RequestImpl {
+
+ /**
+ * The Constant serialVersionUID.
+ */
+ private static final long serialVersionUID = -5798803155055518747L;
+
+ /**
+ * The stork authn request.
+ */
+ private STORKAuthnResponse storkAuthnResponse;
+
+ /**
+ * The stork attr query request.
+ */
+ private STORKAttrQueryResponse storkAttrQueryResponse;
+
+ /**
+ * The action.
+ */
+ String action = null;
+
+ /**
+ * The token
+ */
+ private byte[] storkAuthnResponseToken = null;
+
+ /**
+ * The request id.
+ */
+ private String requestID;
+
+
+ /**
+ * The module.
+ */
+ String module = null;
+
+ /**
+ * The target.
+ */
+ private String target = null;
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#requestedModule()
+ */
+ public String requestedModule() {
+ return this.module;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#requestedAction()
+ */
+ public String requestedAction() {
+ return action;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#getRequestID()
+ */
+ public String getRequestID() {
+ return this.requestID;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#getTarget()
+ */
+ public String getTarget() {
+ return this.target;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#isSSOSupported()
+ */
+ public boolean isSSOSupported() {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#forceAuth()
+ */
+ public boolean forceAuth() {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#setModule(java.lang.String)
+ */
+ public void setModule(String module) {
+ this.module = module;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#setRequestID(java.lang.String)
+ */
+ public void setRequestID(String id) {
+ this.requestID = id;
+ }
+
+ /**
+ * Sets the sTORK authn response.
+ *
+ * @param request the new sTORK authn response
+ */
+ public void setSTORKAuthnResponse(STORKAuthnResponse request) {
+ this.storkAuthnResponse = request;
+ }
+
+ /**
+ * Sets the sTORK authn response token
+ *
+ * @param request the new sTORK authn response token
+ */
+ public void setSTORKAuthnResponseToken(byte[] token) {
+ this.storkAuthnResponseToken = token;
+ }
+
+ /**
+ * Gets the sTORK authn response token .
+ *
+ * @param request the new sTORK authn response
+ */
+ public byte[] getSTORKAuthnResponseToken() {
+ return this.storkAuthnResponseToken;
+ }
+ /**
+ * Sets the sTORK attr response.
+ *
+ * @param request the new sTORK attr response
+ */
+ public void setSTORKAttrResponse(STORKAttrQueryResponse request) {
+ this.storkAttrQueryResponse = request;
+ }
+
+ /**
+ * Checks if the container holds an AttrQuery
+ *
+ * @return true, if is attr response
+ */
+ public boolean isAttrResponse() {
+ return null != storkAttrQueryResponse;
+ }
+
+ /**
+ * Checks if the container holds an AuthnRequest
+ *
+ * @return true, if is authn response
+ */
+ public boolean isAuthnResponse() {
+ return null != storkAuthnResponse;
+ }
+
+
+ /**
+ * Gets the AuthnResponse.
+ *
+ * @return the stork authn response
+ */
+ public STORKAuthnResponse getStorkAuthnResponse() {
+ return this.storkAuthnResponse;
+ }
+
+ /**
+ * Gets the AttrQueryResponse.
+ *
+ * @return the stork attr query response
+ */
+ public STORKAttrQueryResponse getStorkAttrQueryResponse() {
+ return this.storkAttrQueryResponse;
+ }
+
+ /**
+ * Gets the personal attribute list.
+ *
+ * @return the personal attribute list
+ */
+ public IPersonalAttributeList getPersonalAttributeList() {
+ if (isAttrResponse())
+ return this.storkAttrQueryResponse.getPersonalAttributeList();
+ else
+ return this.storkAuthnResponse.getPersonalAttributeList();
+ }
+
+ /**
+ * Sets the personal attribute list.
+ *
+ * @param populateAttributes the new personal attribute list
+ */
+ public void setPersonalAttributeList(PersonalAttributeList populateAttributes) {
+ if (isAttrResponse())
+ this.storkAttrQueryResponse.setPersonalAttributeList(populateAttributes);
+ else
+ this.storkAuthnResponse.setPersonalAttributeList(populateAttributes);
+ }
+
+ /**
+ * Sets the country.
+ *
+ * @param spCountry the new country
+ */
+ public void setCountry(String spCountry) {
+ if (isAttrResponse())
+ this.storkAttrQueryResponse.setCountry(spCountry);
+ else
+ this.storkAuthnResponse.setCountry(spCountry);
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#getOAURL()
+ */
+ public String getOAURL() {
+ if (isAuthnResponse())
+ return storkAuthnResponse.getAudienceRestriction();
+ else if (isAttrResponse())
+ return storkAttrQueryResponse.getAudienceRestriction();
+ else {
+ Logger.error("There is no authentication or attribute request contained in MOASTORKRequest.");
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#isPassiv()
+ */
+ public boolean isPassiv() {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IRequest#setAction(java.lang.String)
+ */
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes()
+ */
+ @Override
+ public List<Attribute> getRequestedAttributes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java
new file mode 100644
index 000000000..a3fac0f6e
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.logging.Logger;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+/**
+ * @author bsuzic
+ * Date: 5/5/14, Time: 2:35 PM
+ */
+public abstract class MandateContainer {
+ protected String mandateIssuePlace = null;
+ protected String mandateIssueDate = null;
+ protected String mandateIssueTime = null;
+ protected String simpleMandateContent = null;
+ protected String mandateValidFrom = null;
+ protected String mandateValidTo = null;
+ protected String annotation = null;
+ protected String physicalRepresentativeIdentificationValue = null;
+ protected String physicalRepresentativeIdentificationType = null;
+ protected String physicalRepresentativeGivenName = null;
+ protected String physicalRepresentativeFamilyName = null;
+ protected String physicalRepresentativeBirthDate = null;
+ protected XPath xPath = null;
+
+
+ public MandateContainer(String mandate) throws XPathExpressionException, MOAIDException {
+ Logger.debug("Received mandate content for processing: " + mandate);
+
+ xPath = XPathFactory.newInstance().newXPath();
+ HashMap<String, String> prefMap = new HashMap<String, String>() {{
+ put(S2Constants.MANDATE_PREFIX, S2Constants.MANDATE_NS);
+ put(S2Constants.PERSONDATA_PREFIX, S2Constants.PERSONDATA_NS);
+ put(S2Constants.XMLDSIG_PREFIX, S2Constants.XMLDSIG_NS);
+ }};
+
+ SimpleNamespaceContext namespace = new SimpleNamespaceContext(prefMap);
+ xPath.setNamespaceContext(namespace);
+ }
+
+
+ public void validateMandateStructure(String localMethods[]) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, MOAIDException {
+ for (String localMethod : localMethods) {
+ Method method = this.getClass().getMethod(localMethod);
+ Object x = method.invoke(this);
+ if ((x == null) || x.toString().length() == 0) {
+ throw new MOAIDException("stork.16", new Object[] {localMethod}); // TODO
+ }
+ }
+ Logger.debug("Mandate structure validated");
+ }
+
+
+ public String getMandateIssuePlace() {
+ return mandateIssuePlace;
+ }
+
+ public void setMandateIssuePlace(String mandateIssuePlace) {
+ this.mandateIssuePlace = mandateIssuePlace;
+ }
+
+ public String getMandateIssueDate() {
+ return mandateIssueDate;
+ }
+
+ public void setMandateIssueDate(String mandateIssueDate) {
+ this.mandateIssueDate = mandateIssueDate;
+ }
+
+ public String getMandateIssueTime() {
+ return mandateIssueTime;
+ }
+
+ public void setMandateIssueTime(String mandateIssueTime) {
+ this.mandateIssueTime = mandateIssueTime;
+ }
+
+ public String getSimpleMandateContent() {
+ return simpleMandateContent;
+ }
+
+ public void setSimpleMandateContent(String simpleMandateContent) {
+ this.simpleMandateContent = simpleMandateContent;
+ }
+
+ public String getMandateValidFrom() {
+ return mandateValidFrom;
+ }
+
+ public void setMandateValidFrom(String mandateValidFrom) {
+ this.mandateValidFrom = mandateValidFrom;
+ }
+
+ public String getMandateValidTo() {
+ return mandateValidTo;
+ }
+
+ public void setMandateValidTo(String mandateValidTo) {
+ this.mandateValidTo = mandateValidTo;
+ }
+
+ public String getPhysicalRepresentativeIdentificationValue() {
+ return physicalRepresentativeIdentificationValue;
+ }
+
+ public void setPhysicalRepresentativeIdentificationValue(String physicalRepresentativeIdentificationValue) {
+ this.physicalRepresentativeIdentificationValue = physicalRepresentativeIdentificationValue;
+ }
+
+ public String getPhysicalRepresentativeIdentificationType() {
+ return physicalRepresentativeIdentificationType;
+ }
+
+ public void setPhysicalRepresentativeIdentificationType(String physicalRepresentativeIdentificationType) {
+ this.physicalRepresentativeIdentificationType = physicalRepresentativeIdentificationType;
+ }
+
+ public String getPhysicalRepresentativeGivenName() {
+ return physicalRepresentativeGivenName;
+ }
+
+ public void setPhysicalRepresentativeGivenName(String physicalRepresentativeGivenName) {
+ this.physicalRepresentativeGivenName = physicalRepresentativeGivenName;
+ }
+
+ public String getPhysicalRepresentativeFamilyName() {
+ return physicalRepresentativeFamilyName;
+ }
+
+ public void setPhysicalRepresentativeFamilyName(String physicalRepresentativeFamilyName) {
+ this.physicalRepresentativeFamilyName = physicalRepresentativeFamilyName;
+ }
+
+ public String getPhysicalRepresentativeBirthDate() {
+ return physicalRepresentativeBirthDate;
+ }
+
+ public void setPhysicalRepresentativeBirthDate(String physicalRepresentativeBirthDate) {
+ // making it conform to STORK dateOfBirth specifications, removing dash
+ this.physicalRepresentativeBirthDate = physicalRepresentativeBirthDate.replaceAll("-","");
+ }
+
+ public String getAnnotation() {
+ return annotation;
+ }
+
+ public void setAnnotation(String annotation) {
+ this.annotation = annotation;
+ }
+
+
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java
new file mode 100644
index 000000000..e58fe804f
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java
@@ -0,0 +1,602 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.BuildException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.*;
+import org.apache.commons.codec.binary.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.regex.Pattern;
+
+/**
+ * Entry point for mandate retrieval. Processes MIS data and transforms into STORK mandate attribute.
+ * Additionally provides eIdentifier attribute (if requested) in order to enable identity correlation
+ */
+public class MandateRetrievalRequest implements IAction {
+
+ private IAuthData authData;
+ private MOASTORKRequest moaStorkRequest;
+ private IdentityLink representingIdentityLink;
+ private Integer QAALevel;
+ private byte[] originalContent;
+
+ public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
+ Logger.debug("Entering AttributeRequest for MandateProvider");
+ httpResp.reset();
+ this.representingIdentityLink = authData.getIdentityLink();
+ this.QAALevel = translateQAALevel(authData.getQAALevel());
+
+ // preparing original content and removing sensitive data from it
+ try {
+ this.originalContent = authData.getMISMandate().getMandate();
+ } catch (Exception e) {
+ Logger.error("Could not extract mandate");
+ Logger.debug(e);
+ throw new MOAIDException("stork.26", new Object[]{});
+ }
+ String originalMandate = StringUtils.newStringUtf8(authData.getMISMandate().getMandate()).replaceAll("<pd:Value>.*?==</pd:Value><pd:Type>urn:publicid:gv.at:baseid</pd:Type>","<pd:Value></pd:Value><pd:Type></pd:Type>");;
+ Logger.debug("Removing personal identification value and type from original mandate ");
+ originalContent = StringUtils.getBytesUtf8(originalMandate);
+
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(req.getOAURL());
+ if (oaParam == null)
+ throw new AuthenticationException("stork.12", new Object[]{req.getOAURL()});
+
+ MOASTORKResponse moaStorkResponse = new MOASTORKResponse();
+ STORKAttrQueryResponse attrResponse = new STORKAttrQueryResponse();
+
+ this.authData = authData;
+
+ if ((req instanceof MOASTORKRequest)) {
+ this.moaStorkRequest = (MOASTORKRequest) req;
+ } else {
+ Logger.error("Internal error - did not receive MOASTORKRequest as expected");
+ throw new MOAIDException("stork.27", new Object[]{});
+ }
+
+
+ if (!(moaStorkRequest.isAttrRequest() || moaStorkRequest.getStorkAttrQueryRequest() == null)) {
+ Logger.error("Did not receive attribute request as expected");
+ throw new MOAIDException("stork.27", new Object[]{});
+ }
+
+ MandateContainer mandateContainer = null;
+
+ try {
+ mandateContainer = new CorporateBodyMandateContainer(new String(authData.getMISMandate().getMandate(), "UTF-8"));
+ } catch (Exception ex) {
+ try {
+ mandateContainer = new PhyPersonMandateContainer(new String(authData.getMISMandate().getMandate(), "UTF-8"));
+ } catch (Exception ex2) {
+ Logger.error("Could not extract data and create mandate container.");
+ throw new MOAIDException("stork.27", new Object[]{});
+ }
+ }
+
+ IPersonalAttributeList sourceAttributeList = moaStorkRequest.getStorkAttrQueryRequest().getPersonalAttributeList();
+
+ IPersonalAttributeList attributeList = new PersonalAttributeList();
+
+ // according to new mapping, only mandate attribute is directly relevant
+ for (PersonalAttribute currentAttribute : sourceAttributeList) {
+ Logger.debug("Evaluating attributes, current attribute: " + currentAttribute.getName());
+ if (currentAttribute.getName().equals("mandateContent")) { // deprecated
+ MandateContentType mandateContent = getMandateContent(mandateContainer, currentAttribute);
+ attributeList.add(marshallComplexAttribute(currentAttribute, mandateContent));
+ } else if (currentAttribute.getName().equals("representative")) { // deprecated
+ RepresentationPersonType representative = getRepresentative(mandateContainer, currentAttribute);
+ attributeList.add(marshallComplexAttribute(currentAttribute, representative));
+ } else if (currentAttribute.getName().equals("represented")) {
+ RepresentationPersonType represented = getRepresented(mandateContainer, currentAttribute);
+ attributeList.add(marshallComplexAttribute(currentAttribute, represented));
+ } else if (currentAttribute.getName().equals("mandate")) {
+ MandateType mandateType = getMandateType(mandateContainer, currentAttribute);
+ attributeList.add(marshallComplexAttribute(currentAttribute, mandateType));
+ } else if (currentAttribute.getName().equals("legalName")) {
+ String legalName = getLegalName(mandateContainer, currentAttribute);
+ if (legalName.length() > 0) {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(legalName), AttributeStatusType.AVAILABLE.value()));
+ } else {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(legalName), AttributeStatusType.NOT_AVAILABLE.value()));
+ }
+ } else if (currentAttribute.getName().equals("eLPIdentifier")) {
+ String eLPIdentifier = geteLPIdentifier(mandateContainer, currentAttribute);
+ if (eLPIdentifier.length() > 0) {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(eLPIdentifier), AttributeStatusType.AVAILABLE.value()));
+ } else {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(eLPIdentifier), AttributeStatusType.NOT_AVAILABLE.value()));
+ }
+ } else if (currentAttribute.getName().equals("type")) {
+ String type = getCompanyType(mandateContainer, currentAttribute);
+ if (type.length() > 0) {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(type), AttributeStatusType.AVAILABLE.value()));
+ } else {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(type), AttributeStatusType.NOT_AVAILABLE.value()));
+ }
+ } else if (currentAttribute.getName().equals("status")) {
+ String status = getCompanyStatus(mandateContainer, currentAttribute);
+ if (status.length() > 0) {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(status), AttributeStatusType.AVAILABLE.value()));
+ } else {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(status), AttributeStatusType.NOT_AVAILABLE.value()));
+ }
+ } else if (currentAttribute.getName().equals("translatableType")) {
+ String translatableType = getCompanyTranslatableType(mandateContainer, currentAttribute);
+ if (translatableType.length() > 0) {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(translatableType), AttributeStatusType.AVAILABLE.value()));
+ } else {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(translatableType), AttributeStatusType.NOT_AVAILABLE.value()));
+ }
+ }
+
+ if (currentAttribute.getName().equals("eIdentifier")) {
+ attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(geteIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(), moaStorkRequest.getStorkAttrQueryRequest().getSpCountry())), AttributeStatusType.AVAILABLE.value()));
+ Logger.info("Adding eIdentifier for mandate holder using SP country: " + moaStorkRequest.getStorkAttrQueryRequest().getSpCountry());
+ }
+
+ }
+
+
+// if (attrResponse.getPersonalAttributeList().size() == 0) {
+// Logger.error("AttributeList empty - could not retrieve attributes");
+// throw new MOAIDException("stork.16", new Object[]{}); // TODO MESSAGE
+// }
+
+ attrResponse.setPersonalAttributeList(attributeList);
+ moaStorkResponse.setSTORKAttrResponse(attrResponse);
+
+ Logger.debug("Attributes retrieved: " + moaStorkResponse.getStorkAttrQueryResponse().getPersonalAttributeList().size() + " for SP country " + attrResponse.getCountry());
+
+ // Prepare extended attributes
+ Logger.debug("Preparing data container");
+
+ // create fresh container
+ DataContainer container = new DataContainer();
+
+ // - fill in the request we extracted above
+ container.setRequest(moaStorkRequest);
+
+ // - fill in the partial response created above
+ container.setResponse(moaStorkResponse);
+
+ container.setRemoteAddress(httpReq.getRemoteAddr());
+
+ Logger.debug("Data container prepared");
+
+ // ask for consent if necessary
+ if (oaParam.isRequireConsentForStorkAttributes())
+ new ConsentEvaluator().requestConsent(container, httpReq, httpResp, authData, oaParam);
+ else
+ new ConsentEvaluator().generateSTORKResponse(httpResp, container);
+
+ return null;
+ }
+
+ private Integer translateQAALevel(String qaaLevel) throws MOAIDException {
+ if (qaaLevel.equals(PVPConstants.STORK_QAA_1_1))
+ return 1;
+ if (qaaLevel.equals(PVPConstants.STORK_QAA_1_2))
+ return 2;
+ if (qaaLevel.equals(PVPConstants.STORK_QAA_1_3))
+ return 3;
+ if (qaaLevel.equals(PVPConstants.STORK_QAA_1_4))
+ return 4;
+ Logger.error("Wrong QAA Number format");
+ throw new MOAIDException("stork.28", new Object[]{});
+ }
+
+ private String geteLPIdentifier(MandateContainer mandateContainer, PersonalAttribute currentAttribute) throws MOAIDException {
+ RepresentationPersonType represented = getRepresented(mandateContainer, currentAttribute);
+ if (mandateContainer instanceof CorporateBodyMandateContainer) {
+ return represented.getELPIdentifier();
+ } else if (currentAttribute.isRequired()) {
+ Logger.error("Cannot provide eLPIdentifier for natural person.");
+ throw new MOAIDException("stork.29", new Object[]{currentAttribute.getName()});
+ }
+ return "";
+ }
+
+ private String geteIdentifier(String identificationType, String identificationValue, String destinationCountry) throws MOAIDException {
+ BPKBuilder bpkBuilder = new BPKBuilder();
+ try {
+ return bpkBuilder.buildStorkeIdentifier(identificationType, identificationValue, destinationCountry);
+ } catch (BuildException be) {
+ Logger.error("Could not build STORK eIdentifier while generating mandate assertion.");
+ throw new MOAIDException("stork.29", new Object[]{});
+ }
+ }
+
+ private PersonalAttribute marshallComplexAttribute(PersonalAttribute currentAttribute, Object obj) { // TODO refactor
+ StringWriter stringWriter = new StringWriter();
+ try {
+ if (obj instanceof MandateContentType) {
+ final Marshaller marshaller = JAXBContext.newInstance(MandateContentType.class).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ marshaller.marshal(new JAXBElement<MandateContentType>(new QName("urn:eu:stork:names:tc:STORK:1.0:assertion", currentAttribute.getName()), MandateContentType.class, null, (MandateContentType) obj), stringWriter);
+ } else if (obj instanceof MandateType) {
+ final Marshaller marshaller = JAXBContext.newInstance(MandateType.class).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ marshaller.marshal(new JAXBElement<MandateType>(new QName("urn:eu:stork:names:tc:STORK:1.0:assertion", currentAttribute.getName()), MandateType.class, null, (MandateType) obj), stringWriter);
+ } else if (obj instanceof RepresentationPersonType) {
+ final Marshaller marshaller = JAXBContext.newInstance(RepresentationPersonType.class).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ marshaller.marshal(new JAXBElement<RepresentationPersonType>(new QName("urn:eu:stork:names:tc:STORK:1.0:assertion", currentAttribute.getName()), RepresentationPersonType.class, null, (RepresentationPersonType) obj), stringWriter);
+ }
+
+ } catch (Exception ex) {
+ Logger.error("Could not marshall atrribute: " + currentAttribute.getName() + ", " + ex.getMessage());
+ return new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), new ArrayList<String>(), AttributeStatusType.NOT_AVAILABLE.value());
+ }
+ ArrayList<String> value = new ArrayList<String>();
+ value.add(stringWriter.toString());
+
+ PersonalAttribute personalAttribute = new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), value, AttributeStatusType.AVAILABLE.value());
+ return personalAttribute;
+ }
+
+
+ private String mapPowersType(MandateContainer mandateContainer) {
+ Logger.debug("Analyzing mandate of type: " + mandateContainer.getAnnotation() + ".");
+ // using if for java 6 compatibility if necessary
+ if (mandateContainer.getAnnotation().equals("ELGABilateral")) {
+ return "6"; // Health Powers
+ } else if (mandateContainer.getAnnotation().equals("ERsB")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Gesetzliche Vollmacht auf Basis Ergäzungsregister für sonstige Betroffene")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Gesetzliche Vollmacht auf Basis Ergänzungsregister für sonstige Betroffene")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().contains("Gesetzliche Vollmacht auf Basis Erg")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("GeneralvollmachtBilateral")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().contains("Gesetzliche Vollmacht auf Basis Firmenbuch")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("ERsBMitPostvollmacht")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("ZVR")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("ZVRMitPostvollmacht")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("EVB")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Einzelvertretungsbefugnis")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Prokura")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Notar")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Organwalter")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Rechtsanwalt")) {
+ return "0"; // General Powers
+ } else if (mandateContainer.getAnnotation().equals("Ziviltechniker")) {
+ return "0"; // General Powers
+ }
+ Logger.debug("Returning other type of mandate");
+ return "9";
+ }
+
+ private MandateType getMandateType(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ MandateType mandateType = new MandateType();
+ RepresentationPersonType representative = getRepresentative(mandateContainer, sourceAttribute);
+ RepresentationPersonType represented = getRepresented(mandateContainer, sourceAttribute);
+ MandateContentType mandateContent = getMandateContent(mandateContainer, sourceAttribute);
+ mandateType.setRepresentative(representative);
+ mandateType.setRepresented(represented);
+ mandateType.getMandateContent().add(mandateContent);
+ Logger.debug("Complex attribute extracted: " + sourceAttribute.getName());
+ return mandateType;
+ }
+
+ private String getLegalName(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ RepresentationPersonType represented = getRepresented(mandateContainer, sourceAttribute);
+ if (mandateContainer instanceof CorporateBodyMandateContainer) {
+ represented.getLegalName();
+ //return represented.getName();
+ } else if (sourceAttribute.isRequired()) {
+ Logger.error("Cannot provide legalName for natural person.");
+ throw new MOAIDException("stork.19", new Object[]{sourceAttribute.getName()});
+ }
+ return "";
+ }
+
+
+ private String getLegalIdentificationType(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ if (mandateContainer instanceof CorporateBodyMandateContainer) {
+ return ((CorporateBodyMandateContainer) mandateContainer).getCorpMandatorIdentificationType();
+ } else if (sourceAttribute.isRequired()) {
+ Logger.error("Cannot provide type for natural person.");
+ throw new MOAIDException("stork.19", new Object[]{sourceAttribute.getName()}); // TODO
+ }
+ return "";
+ }
+
+ private String getCompanyStatus(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ String legalName = getLegalName(mandateContainer, sourceAttribute);
+ if (legalName.contains("in Liquidation") || legalName.contains("in Liqu.")) {
+ return "L"; // liqudation
+ }
+ return "R";
+ }
+
+ private String getCompanyType(String legalName, String legalIdentificationType, PersonalAttribute sourceAttrivbute) throws MOAIDException {
+ // compile patterns for different organisation types
+ // sources: USP, WKO, LexAndTax
+
+ // gmbh patterns
+ ArrayList<Pattern> gmbhPatterns = new ArrayList<Pattern>();
+ gmbhPatterns.add(Pattern.compile(".+ GmbH(( in Liquidation)|( in Liqu.)){0,1}$"));
+ gmbhPatterns.add(Pattern.compile(".+ GesmbH$"));
+ gmbhPatterns.add(Pattern.compile(".+ Gesellschaft mit beschränkter Haftung$"));
+ gmbhPatterns.add(Pattern.compile(".+ Ges\\.m\\.b\\.H\\.$"));
+ gmbhPatterns.add(Pattern.compile(".+ G\\.m\\.b\\.H\\.$"));
+ gmbhPatterns.add(Pattern.compile(".+ Handelsges\\.m\\.b\\.H\\.$"));
+ gmbhPatterns.add(Pattern.compile(".+ Gesellschaft m\\.b\\.H\\.$"));
+
+ // ag patterns
+ ArrayList<Pattern> agPatterns = new ArrayList<Pattern>();
+ agPatterns.add(Pattern.compile(".+ AG$"));
+ agPatterns.add(Pattern.compile(".+ Aktiengesellschaft$"));
+
+ // og patterns
+ ArrayList<Pattern> ogPatterns = new ArrayList<Pattern>();
+ ogPatterns.add(Pattern.compile(".+ OG$"));
+ ogPatterns.add(Pattern.compile(".+ OHG$"));
+ ogPatterns.add(Pattern.compile(".+ offene Gesellschaft$"));
+
+ // kg patterns
+ ArrayList<Pattern> kgPatterns = new ArrayList<Pattern>();
+ kgPatterns.add(Pattern.compile(".+ KG$"));
+ kgPatterns.add(Pattern.compile(".+ Kommanditgesellschaft$"));
+
+ // eu patterns
+ ArrayList<Pattern> euPatterns = new ArrayList<Pattern>();
+ euPatterns.add(Pattern.compile(".+ eingetragene Unternehmerin$"));
+ euPatterns.add(Pattern.compile(".+ eingetragener Unternehmer$"));
+ euPatterns.add(Pattern.compile(".+ e\\.U\\.$"));
+
+
+ // company patterns
+ HashMap<String, ArrayList<Pattern>> companyPatterns = new HashMap<String, ArrayList<Pattern>>();
+ companyPatterns.put("GmbH", gmbhPatterns);
+ companyPatterns.put("AG", agPatterns);
+ companyPatterns.put("OG", ogPatterns);
+ companyPatterns.put("KG", kgPatterns);
+ companyPatterns.put("e.U.", euPatterns);
+
+ // iterate over different types of companies and check if the name ending matches
+ if (S2Constants.IDENTIFICATION_TYPE_COMPANY.equals(legalIdentificationType)) {
+ for (String companyType : companyPatterns.keySet()) {
+ for (Pattern pattern : companyPatterns.get(companyType)) {
+ if (pattern.matcher(legalName).matches()) {
+ return companyType;
+ }
+ }
+ }
+ }
+
+ // check if the subject is association
+ if (S2Constants.IDENTIFICATION_TYPE_ASSOCIATION.equals(legalIdentificationType)) {
+ return "Verein";
+ }
+
+ // check if the subject falls under category of others
+ if (S2Constants.IDENTIFICATION_TYPE_OTHERS.equals(legalIdentificationType)) {
+ return "ERsB";
+ }
+
+ return "";
+ }
+
+ private String getCompanyType(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ // retrieve the registered subject name and identification type
+ String legalName = getLegalName(mandateContainer, sourceAttribute);
+ String legalIdentificationType = getLegalIdentificationType(mandateContainer, sourceAttribute);
+ return getCompanyType(legalName, legalIdentificationType, sourceAttribute);
+ }
+
+ private String getCompanyTranslatableType(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ // retrieve first the company type
+ String companyType = getCompanyType(mandateContainer, sourceAttribute);
+
+ // translate company type based on the section 5.6 in STORK 2 D4.11
+ if (companyType.length() == 0) {
+ return "";
+ } else if (companyType.equals("GmbH")) {
+ return "G";
+ } else if (companyType.equals("AG")) {
+ return "A";
+ } else if (companyType.equals("OG")) {
+ return "O";
+ } else if (companyType.equals("KG")) {
+ return "K";
+ } else {
+ return "";
+ }
+ }
+
+
+ private String getRepresentedStorkeIdentifier(MandateContainer mandateContainer) throws MOAIDException {
+
+ if (!(mandateContainer instanceof PhyPersonMandateContainer)) {
+ Logger.error("Physical person mandate container missing");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ PhyPersonMandateContainer phyPersonMandateContainer = (PhyPersonMandateContainer) mandateContainer;
+
+ if (!phyPersonMandateContainer.getPhyPersMandatorIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
+ Logger.error("Identification type of represented person from MIS is not correct");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ if (phyPersonMandateContainer.getPhyPersMandatorIdentificationValue().length() != 24) {
+ Logger.error("Identification value of represented person from MIS is not correct");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ if ((this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry() == null) || (this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry().length() == 0)) {
+ Logger.error("Error accessing SP country code");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ return geteIdentifier(phyPersonMandateContainer.getPhyPersMandatorIdentificationType(), phyPersonMandateContainer.getPhyPersMandatorIdentificationValue(), this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry());
+ }
+
+ private String getRepresentingStorkeIdentifier(MandateContainer mandateContainer) throws MOAIDException {
+ if ((this.representingIdentityLink == null)) {
+ Logger.error("Error accessing identityLink while fetching mandate attribute");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ if ((this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry() == null) || (this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry().length() == 0)) {
+ Logger.error("Error accessing SP country code");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ if (!this.representingIdentityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
+ Logger.error("Incorrect identity link (local): identification type is not correct! Got: " + this.representingIdentityLink.getIdentificationType());
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ if (!mandateContainer.getPhysicalRepresentativeIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
+ Logger.error("Incorrect identity link (MIS): identification type is not correct! Got: " + this.representingIdentityLink.getIdentificationType() + " (representingIdentityLink) and " + mandateContainer.getPhysicalRepresentativeIdentificationType() + " (mandateContainer.phyRepresentative)");
+ Logger.debug("mandatecontainervalue: " + mandateContainer.getPhysicalRepresentativeIdentificationValue() + ", representingidentitylinkvalue: " + this.representingIdentityLink.getIdentificationValue());
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ if (!mandateContainer.getPhysicalRepresentativeIdentificationValue().equals(this.representingIdentityLink.getIdentificationValue())) {
+ Logger.error("Identification values from MIS and local service are not equal!");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ BPKBuilder bpkBuilder = new BPKBuilder();
+ try {
+ return bpkBuilder.buildStorkeIdentifier(this.representingIdentityLink, this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry());
+ } catch (BuildException be) {
+ Logger.error("Could not build STORK eIdentifier while generating mandate assertion.");
+ throw new MOAIDException("stork.20", new Object[]{}); // TODO
+ }
+
+ }
+
+ private RepresentationPersonType getRepresentative(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ RepresentationPersonType representative = new RepresentationPersonType();
+
+ representative.setEIdentifier(getRepresentingStorkeIdentifier(mandateContainer));
+ representative.setGivenName(mandateContainer.getPhysicalRepresentativeGivenName());
+ representative.setSurname(mandateContainer.getPhysicalRepresentativeFamilyName());
+ representative.setDateOfBirth(mandateContainer.getPhysicalRepresentativeBirthDate());
+
+ Logger.debug("Complex attribute extracted: " + sourceAttribute.getName());
+ return representative;
+ }
+
+ private RepresentationPersonType getRepresented(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ RepresentationPersonType represented = new RepresentationPersonType();
+
+ if (mandateContainer instanceof CorporateBodyMandateContainer) {
+ CorporateBodyMandateContainer corporateBodyMandateContainer = (CorporateBodyMandateContainer) mandateContainer;
+ represented.setELPIdentifier(corporateBodyMandateContainer.getCorpMandatorIdentificationValue());
+ represented.setLegalName(corporateBodyMandateContainer.getCorpMandatorFullName());
+ represented.setTextRegisteredAddress(null);
+ represented.setCanonicalRegisteredAddress(new CanonicalAddressType());
+ represented.setLegalForm(getCompanyType(corporateBodyMandateContainer.corpMandatorFullName, corporateBodyMandateContainer.corpMandatorIdentificationType, sourceAttribute));
+ } else if (mandateContainer instanceof PhyPersonMandateContainer) {
+ PhyPersonMandateContainer phyPersonMandateContainer = (PhyPersonMandateContainer) mandateContainer;
+ represented.setEIdentifier(getRepresentedStorkeIdentifier(mandateContainer));
+ represented.setGivenName(phyPersonMandateContainer.getPhyPersMandatorGivenName());
+ represented.setSurname(phyPersonMandateContainer.getPhyPersMandatorFamilyName());
+ represented.setDateOfBirth(phyPersonMandateContainer.getPhyPersMandatorBirthDate());
+ }
+
+ Logger.debug("Complex attribute extracted: " + sourceAttribute.getName());
+
+ return represented;
+ }
+
+
+ private MandateContentType getMandateContent(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException {
+ MandateContentType mandateContent = new MandateContentType();
+ try {
+ XMLGregorianCalendar validFrom = DatatypeFactory.newInstance().newXMLGregorianCalendar(mandateContainer.getMandateValidFrom());
+ XMLGregorianCalendar validTo = DatatypeFactory.newInstance().newXMLGregorianCalendar(mandateContainer.getMandateValidTo());
+ TimeRestrictionType timeRestriction = new TimeRestrictionType();
+ timeRestriction.setValidFrom(validFrom);
+ timeRestriction.setValidTo(validTo);
+ mandateContent.setTimeRestriction(timeRestriction);
+ } catch (DatatypeConfigurationException dte) {
+ Logger.error("Error converting date from mandate: " + mandateContainer.getMandateValidFrom() + ", " + mandateContainer.getMandateValidTo());
+ throw new MOAIDException("stork.20", new Object[]{});
+ }
+ mandateContent.setAQAA(this.QAALevel);
+ mandateContent.setOriginalMandate(originalContent);
+ mandateContent.setOriginalMandateType("application/xml");
+ TransactionLimitRestrictionType transactionLimit = new TransactionLimitRestrictionType();
+ mandateContent.setTransactionLimit(transactionLimit);
+ mandateContent.setIsJoint("");
+ mandateContent.setIsChained(false);
+ mandateContent.setTypeOfPower(mapPowersType(mandateContainer)); // TODO check
+ Logger.debug("Complex attribute extracted: " + sourceAttribute.getName());
+ return mandateContent;
+ }
+
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ return true;
+ }
+
+ public String getDefaultActionName() {
+ return STORKProtocol.MANDATERETRIEVALREQUEST;
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java
new file mode 100644
index 000000000..c715b65eb
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.logging.Logger;
+import org.xml.sax.InputSource;
+
+import javax.xml.xpath.XPathExpressionException;
+import java.io.StringReader;
+
+/**
+ * Physical person representing physical person
+ * @author bsuzic
+ * Date: 4/30/14, Time: 11:29 AM
+ */
+public class PhyPersonMandateContainer extends MandateContainer {
+
+ private String phyPersMandatorIdentificationValue = null;
+ private String phyPersMandatorIdentificationType = null;
+ private String phyPersMandatorGivenName = null;
+ private String phyPersMandatorFamilyName = null;
+ private String phyPersMandatorBirthDate = null;
+
+ String localMethods[] = new String[]{"getPhyPersMandatorGivenName", "getPhyPersMandatorFamilyName", "getPhyPersMandatorBirthDate", "getPhyPersMandatorIdentificationValue",
+ "getPhyPersMandatorIdentificationType", "getMandateIssuePlace", "getMandateIssueDate", "getMandateIssueTime", "getSimpleMandateContent", "getMandateValidFrom",
+ "getMandateValidTo", "getPhysicalRepresentativeIdentificationValue", "getPhysicalRepresentativeIdentificationType", "getAnnotation",
+ "getPhysicalRepresentativeGivenName", "getPhysicalRepresentativeFamilyName", "getPhysicalRepresentativeBirthDate"
+ };
+
+
+ public PhyPersonMandateContainer(String mandate) throws XPathExpressionException, MOAIDException {
+ super(mandate);
+
+ setAnnotation(xPath.evaluate(S2Constants.MANDATE_ANNOTATION_QUERY, new InputSource(new StringReader(mandate))));
+ setPhyPersMandatorIdentificationType(xPath.evaluate(S2Constants.MANDATE_MANDATOR_PHYPERS_IDTYPE_QUERY, new InputSource(new StringReader(mandate))));
+ setPhyPersMandatorIdentificationValue(xPath.evaluate(S2Constants.MANDATE_MANDATOR_PHYPERS_IDVALUE_QUERY, new InputSource(new StringReader(mandate))));
+ setPhyPersMandatorGivenName(xPath.evaluate(S2Constants.MANDATE_MANDATOR_PHYPERS_GIVENNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setPhyPersMandatorFamilyName(xPath.evaluate(S2Constants.MANDATE_MANDATOR_PHYPERS_FAMILYNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setPhyPersMandatorBirthDate(xPath.evaluate(S2Constants.MANDATE_MANDATOR_PHYPERS_DATEOFBIRTH_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateIssueDate(xPath.evaluate(S2Constants.MANDATE_ISSUEDDATE_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateIssuePlace(xPath.evaluate(S2Constants.MANDATE_ISSUEDPLACE_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateIssueTime(xPath.evaluate(S2Constants.MANDATE_ISSUEDTIME_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateValidFrom(xPath.evaluate(S2Constants.MANDATE_SIMPLEMANDATECONTENT_VALIDFROM_QUERY, new InputSource(new StringReader(mandate))));
+ setMandateValidTo(xPath.evaluate(S2Constants.MANDATE_SIMPLEMANDATECONTENT_VALIDTO_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeBirthDate(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_DATEOFBIRTH_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeFamilyName(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_FAMILYNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeGivenName(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_GIVENNAME_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeIdentificationType(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_IDTYPE_QUERY, new InputSource(new StringReader(mandate))));
+ setPhysicalRepresentativeIdentificationValue(xPath.evaluate(S2Constants.MANDATE_REPRESENTATIVE_PHYPERS_IDVALUE_QUERY, new InputSource(new StringReader(mandate))));
+ setSimpleMandateContent(xPath.evaluate(S2Constants.MANDATE_SIMPLEMANDATECONTENT_TXTDESC_QUERY, new InputSource(new StringReader(mandate))));
+
+ // check if all necessary fields are present
+ Logger.debug("Starting mandate structure validation");
+ try {
+ validateMandateStructure(localMethods); // TODO
+ } catch (Exception e) {
+ if (e instanceof MOAIDException) {
+ Logger.error("Could not validate mandate structure.");
+ throw new MOAIDException("stork.16", new Object[] {e.getMessage()}); // TODO
+ } else {
+ Logger.error("Error during mandate structure validation.");
+ throw new MOAIDException("stork.16", new Object[] {e.getMessage()}); // TODO
+ }
+
+ }
+ }
+
+
+
+ public String getPhyPersMandatorGivenName() {
+ return phyPersMandatorGivenName;
+ }
+
+ public void setPhyPersMandatorGivenName(String phyPersMandatorGivenName) {
+ this.phyPersMandatorGivenName = phyPersMandatorGivenName;
+ }
+
+ public String getPhyPersMandatorFamilyName() {
+ return phyPersMandatorFamilyName;
+ }
+
+ public void setPhyPersMandatorFamilyName(String phyPersMandatorFamilyName) {
+ this.phyPersMandatorFamilyName = phyPersMandatorFamilyName;
+ }
+
+ public String getPhyPersMandatorBirthDate() {
+ return phyPersMandatorBirthDate;
+ }
+
+ public void setPhyPersMandatorBirthDate(String phyPersMandatorBirthDate) {
+ // making it conform to STORK dateOfBirth specifications, removing dash
+ this.phyPersMandatorBirthDate = phyPersMandatorBirthDate.replaceAll("-","");
+ }
+
+ public String getPhyPersMandatorIdentificationValue() {
+ return phyPersMandatorIdentificationValue;
+ }
+
+ public void setPhyPersMandatorIdentificationValue(String phyPersMandatorIdentificationValue) {
+ this.phyPersMandatorIdentificationValue = phyPersMandatorIdentificationValue;
+ }
+
+ public String getPhyPersMandatorIdentificationType() {
+ return phyPersMandatorIdentificationType;
+ }
+
+ public void setPhyPersMandatorIdentificationType(String phyPersMandatorIdentificationType) {
+ this.phyPersMandatorIdentificationType = phyPersMandatorIdentificationType;
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/S2Constants.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/S2Constants.java
new file mode 100644
index 000000000..a560bdaff
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/S2Constants.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+/**
+ * @author bsuzic
+ * Date: 4/29/14, Time: 5:34 PM
+ */
+public interface S2Constants {
+ public static final String MANDATE_PREFIX = "mandate";
+ public static final String PERSONDATA_PREFIX = "persondata";
+ public static final String XMLDSIG_PREFIX = "xmldsig";
+
+ public static final String MANDATE_NS = "http://reference.e-government.gv.at/namespace/mandates/20040701#";
+ public static final String PERSONDATA_NS = "http://reference.e-government.gv.at/namespace/persondata/20020228#";
+ public static final String XMLDSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
+
+ public static final String MANDATE_ANNOTATION_QUERY = "/mandate:Mandate/mandate:Annotation/text()";
+ public static final String MANDATE_REPRESENTATIVE_PHYPERS_IDVALUE_QUERY = "/mandate:Mandate/mandate:Representative/persondata:PhysicalPerson/persondata:Identification/persondata:Value/text()";
+ public static final String MANDATE_REPRESENTATIVE_PHYPERS_IDTYPE_QUERY = "/mandate:Mandate/mandate:Representative/persondata:PhysicalPerson/persondata:Identification/persondata:Type/text()";
+ public static final String MANDATE_REPRESENTATIVE_PHYPERS_GIVENNAME_QUERY = "/mandate:Mandate/mandate:Representative/persondata:PhysicalPerson/persondata:Name/persondata:GivenName/text()";
+ public static final String MANDATE_REPRESENTATIVE_PHYPERS_FAMILYNAME_QUERY = "/mandate:Mandate/mandate:Representative/persondata:PhysicalPerson/persondata:Name/persondata:FamilyName/text()";
+ public static final String MANDATE_REPRESENTATIVE_PHYPERS_DATEOFBIRTH_QUERY = "/mandate:Mandate/mandate:Representative/persondata:PhysicalPerson/persondata:DateOfBirth/text()";
+ public static final String MANDATE_MANDATOR_CORPBODY_IDVALUE_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:CorporateBody/persondata:Identification/persondata:Value/text()";
+ public static final String MANDATE_MANDATOR_CORPBODY_IDTYPE_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:CorporateBody/persondata:Identification/persondata:Type/text()";
+ public static final String MANDATE_MANDATOR_CORPBODY_FULLNAME_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:CorporateBody/persondata:FullName/text()";
+ public static final String MANDATE_ISSUEDPLACE_QUERY = "/mandate:Mandate/mandate:Issued/mandate:Place/text()";
+ public static final String MANDATE_ISSUEDDATE_QUERY = "/mandate:Mandate/mandate:Issued/mandate:Date/text()";
+ public static final String MANDATE_ISSUEDTIME_QUERY = "/mandate:Mandate/mandate:Issued/mandate:Time/text()";
+ public static final String MANDATE_SIMPLEMANDATECONTENT_TXTDESC_QUERY = "/mandate:Mandate/mandate:SimpleMandateContent/mandate:TextualDescription/text()";
+ public static final String MANDATE_SIMPLEMANDATECONTENT_VALIDFROM_QUERY = "/mandate:Mandate/mandate:SimpleMandateContent/mandate:TimeConstraint/mandate:ValidFrom/text()";
+ public static final String MANDATE_SIMPLEMANDATECONTENT_VALIDTO_QUERY = "/mandate:Mandate/mandate:SimpleMandateContent/mandate:TimeConstraint/mandate:ValidTo/text()";
+
+ public static final String MANDATE_MANDATOR_PHYPERS_IDVALUE_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:PhysicalPerson/persondata:Identification/persondata:Value/text()";
+ public static final String MANDATE_MANDATOR_PHYPERS_IDTYPE_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:PhysicalPerson/persondata:Identification/persondata:Type/text()";
+ public static final String MANDATE_MANDATOR_PHYPERS_GIVENNAME_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:PhysicalPerson/persondata:Name/persondata:GivenName/text()";
+ public static final String MANDATE_MANDATOR_PHYPERS_FAMILYNAME_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:PhysicalPerson/persondata:Name/persondata:FamilyName/text()";
+ public static final String MANDATE_MANDATOR_PHYPERS_DATEOFBIRTH_QUERY = "/mandate:Mandate/mandate:Mandator/persondata:PhysicalPerson/persondata:DateOfBirth/text()";
+
+ public static final String IDENTIFICATION_TYPE_COMPANY = "urn:publicid:gv.at:baseid+XFN";
+ public static final String IDENTIFICATION_TYPE_ASSOCIATION = "urn:publicid:gv.at:baseid+XZVR";
+ public static final String IDENTIFICATION_TYPE_OTHERS = "urn:publicid:gv.at:baseid+XERSB";
+
+
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKPVPUtilits.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKPVPUtilits.java
new file mode 100644
index 000000000..123d32af4
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKPVPUtilits.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author tlenz
+ *
+ */
+public class STORKPVPUtilits {
+
+ public static final List<String> attributesRequirePVPAuthentication =
+ Arrays.asList("ECApplicationRole", "MSOrganization");
+
+
+
+ public static boolean performAuthenticationOnNationalIDP(MOASTORKRequest moastorkRequest) {
+ for (String el : attributesRequirePVPAuthentication) {
+ if (moastorkRequest.getPersonalAttributeList().containsKey(el)) {
+ return true;
+
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java
new file mode 100644
index 000000000..071b5ae8a
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IModulInfo;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.stork.peps.auth.commons.*;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+
+/**
+ * Stork 2 Protocol Support
+ *
+ * @author bsuzic
+ */
+public class STORKProtocol extends MOAIDAuthConstants implements IModulInfo {
+
+ public static final String NAME = STORKProtocol.class.getName();
+ public static final String PATH = "id_stork2";
+
+ public static final String AUTHENTICATIONREQUEST = "AuthenticationRequest";
+ public static final String ATTRIBUTE_COLLECTOR = "AttributeCollector";
+ public static final String MANDATERETRIEVALREQUEST = "MandateRetrievalRequest";
+ public static final String CONSENT_EVALUATOR = "ConsentEvaluator";
+
+ private static HashMap<String, IAction> actions = new HashMap<String, IAction>();
+
+ static {
+ actions.put(AUTHENTICATIONREQUEST, new AuthenticationRequest());
+ actions.put(ATTRIBUTE_COLLECTOR, new AttributeCollector());
+ actions.put(CONSENT_EVALUATOR, new ConsentEvaluator());
+ actions.put(MANDATERETRIEVALREQUEST, new MandateRetrievalRequest());
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public String getPath() {
+ return PATH;
+ }
+
+ public IAction getAction(String action) {
+ return actions.get(action);
+ }
+
+ public STORKProtocol() {
+ super();
+ }
+
+ /*
+ First request step - send it to BKU selection for user authentication. After the user credentials
+ and other info are obtained, in the second step the request will be processed and the user redirected
+ */
+ public IRequest preProcess(HttpServletRequest request, HttpServletResponse response, String action,
+ String sessionId, String transactionId) throws MOAIDException {
+ Logger.info("Starting preprocessing for Stork2 protocol");
+ Logger.debug("Request method: " + request.getMethod());
+ Logger.debug("Request content length: " + request.getContentLength());
+ Logger.debug("Initiating action: " + action);
+
+ MOASTORKRequest STORK2Request = new MOASTORKRequest();
+ MOASTORKResponse STORK2Response = new MOASTORKResponse();
+
+
+ if (AttributeCollector.class.getSimpleName().equals(action) || ConsentEvaluator.class.getSimpleName().equals(action))
+ return STORK2Request;
+
+
+ if (request.getParameter("SAMLResponse") != null) { // TODO check attribute collector
+ //extract STORK Response from HTTP Request
+ byte[] decSamlToken;
+ try {
+ decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse"));
+ } catch (NullPointerException e) {
+ if (request.getRemoteHost().contains("129.27.142")) {
+ Logger.warn("Availability check by " + request.getRemoteHost() + " on URI: " + request.getRequestURI());
+ } else {
+ Logger.error("Unable to retrieve STORK Request for host: " + request.getRemoteHost() + " and URI: " + request.getRequestURI(), e);
+ }
+ throw new MOAIDException("stork.04", null);
+ }
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+
+ STORKAuthnResponse authnResponse = null;
+
+
+ // check if valid authn request is contained
+ try {
+ authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, request.getRemoteAddr());
+ } catch (STORKSAMLEngineException ex) {
+ Logger.error("Unable to validate Stork AuthenticationResponse: " + ex.getMessage());
+ }
+
+ STORK2Response.setSTORKAuthnResponseToken(decSamlToken);
+
+ return STORK2Response;
+
+ } else if (request.getParameter("SAMLRequest") != null) {
+
+ //extract STORK Response from HTTP Request
+ byte[] decSamlToken;
+ try {
+ decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLRequest"));
+ } catch (NullPointerException e) {
+ if (request.getRemoteHost().contains("129.27.142")) {
+ Logger.warn("Availability check by " + request.getRemoteHost() + " on URI: " + request.getRequestURI());
+ } else {
+ Logger.error("Unable to retrieve STORK Request for host: " + request.getRemoteHost() + " and URI: " + request.getRequestURI(), e);
+ }
+ throw new MOAIDException("stork.04", null);
+ }
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+
+ STORKAuthnRequest authnRequest = null;
+ STORKAttrQueryRequest attrRequest = null;
+
+ // check if valid authn request is contained
+ try {
+ authnRequest = engine.validateSTORKAuthnRequest(decSamlToken);
+
+ } catch (STORKSAMLEngineException ex) {
+ Logger.error("Unable to validate Stork AuthenticationRequest: " + ex.getMessage());
+
+ } catch (ClassCastException e) {
+ // we do not have a authnRequest
+ // check if a valid attr request is container
+ try {
+ attrRequest = engine.validateSTORKAttrQueryRequest(decSamlToken);
+
+ } catch (STORKSAMLEngineException ex) {
+ Logger.error("Unable to validate Stork AuthenticationRequest: " + ex.getMessage());
+
+ }
+ }
+
+ // if there is no authn or attr request, raise error
+ if ((authnRequest == null) && (attrRequest == null)) {
+ Logger.error("There is no authentication or attribute request contained.");
+ throw new MOAIDException("stork.14", null);
+ }
+ // list attributes in the request
+ try {
+ for (PersonalAttribute personalAttribute : authnRequest.getPersonalAttributeList()) {
+ Logger.debug("Personal attribute found in request: " + personalAttribute.getName() + " isRequired: " + personalAttribute.isRequired());
+ }
+ } catch (Exception e) {
+ Logger.error("Exception, attributes: " + e.getMessage());
+ }
+
+ STORK2Request.setSTORKAuthnRequest(authnRequest);
+ STORK2Request.setSTORKAttrRequest(attrRequest);
+
+ //check if OA is instance of VIDP or STORKPVPGateway
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(STORK2Request.getOAURL());
+ if (oaParam == null)
+ throw new AuthenticationException("stork.12", new Object[]{STORK2Request.getOAURL()});
+
+ else {
+ STORK2Request.setOnlineApplicationConfiguration(oaParam);
+ if (oaParam.isSTORKPVPGateway()) {
+ if (MiscUtil.isNotEmpty(oaParam.getSTORKPVPForwardEntity())) {
+ Logger.info("Received request for STORK->PVP gateway. " +
+ "Forward to PVP portal with entiyID " + oaParam.getSTORKPVPForwardEntity() +
+ " ..." );
+ STORK2Request.setRequestedIDP(oaParam.getSTORKPVPForwardEntity());
+
+ } else {
+ Logger.error("InterfederatedGateway configuration with ID " + STORK2Request.getOAURL() +
+ " not configure a forward entityID.");
+ throw new MOAIDException("", null);
+
+ }
+ }
+
+ }
+
+ return STORK2Request;
+ } else {
+ throw new MOAIDException("stork.14", null); // TODO Specify message
+ }
+ }
+
+ public IAction canHandleRequest(HttpServletRequest request, HttpServletResponse response) {
+ return null;
+ }
+
+ public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable {
+ return false;
+ }
+
+ public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) {
+ return false;
+ }
+}
+
+
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/SimpleNamespaceContext.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/SimpleNamespaceContext.java
new file mode 100644
index 000000000..2c2df3e54
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/SimpleNamespaceContext.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.xml.namespace.NamespaceContext;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SimpleNamespaceContext implements NamespaceContext {
+
+ HashMap<String, String> prefMap = null;
+ /**
+ * @param prefMap
+ */
+ SimpleNamespaceContext(HashMap<String, String> prefMap) {
+ this.prefMap = prefMap;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String)
+ */
+ @Override
+ public String getNamespaceURI(String prefix) {
+ if (prefMap.containsKey(prefix))
+ return prefMap.get(prefix);
+ else
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String)
+ */
+ @Override
+ public String getPrefix(String namespaceURI) {
+ if (prefMap.containsValue(namespaceURI)) {
+ Set<Entry<String, String>> set = prefMap.entrySet();
+ for (Entry<String, String> el : set) {
+ if (el.getValue().equals(namespaceURI))
+ return el.getKey();
+
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String)
+ */
+ @Override
+ public Iterator getPrefixes(String namespaceURI) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java
new file mode 100644
index 000000000..31b9c9c0a
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2;
+
+public class UnsupportedAttributeException extends Exception {
+
+ private static final long serialVersionUID = -7720066381435378111L;
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/AttributeProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/AttributeProvider.java
new file mode 100644
index 000000000..aaf13a779
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/AttributeProvider.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2.attributeproviders;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException;
+import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+
+/**
+ * An {@link AttributeProvider} can fetch a set of stork attributes. It might complete the query within one method call,
+ * but might also need to redirect to another webservice to accomplish its task.
+ */
+public abstract class AttributeProvider implements Comparable<AttributeProvider>{
+
+ protected String attributes;
+
+ public AttributeProvider(String attributes){
+ this.attributes = attributes;
+ }
+
+ /**
+ * Acquire the specified attribute. Returns {@code null} when attribute retrieval is in progress, but requires for
+ * for redirecting the user to an external service. Use {@link AttributeProvider#parse(HttpServletRequest)} to parse
+ * the response.
+ *
+ * @param currentProviderConfiguredAttributes the list of attributes to be acquired
+ * @param moastorkRequest the sp county code
+ * @param authData the moasession
+ * @return the personal attribute
+ * @throws UnsupportedAttributeException the unsupported attribute exception
+ * @throws ExternalAttributeRequestRequiredException an attribute request to an external service has to be done
+ * @throws MOAIDException the mOAID exception
+ */
+ protected abstract IPersonalAttributeList acquire(PersonalAttribute currentProviderConfiguredAttributes, MOASTORKRequest moastorkRequest, IAuthData authData) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException, MOAIDException;
+
+ public IPersonalAttributeList acquire(List<PersonalAttribute> attributes, MOASTORKRequest moastorkRequest, IAuthData authData) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException, MOAIDException {
+ if (attributes.size() == 1) {
+ return acquire(attributes.get(0), moastorkRequest, authData);
+ } else {
+ throw new MOAIDException("stork.13", new Object[] { }); // TODO message only one attribute supported by this provider
+
+ }
+ }
+
+ /**
+ * Perform redirect.
+ *
+ * @param url the return URL ending with ?artifactId=...
+ * @param req the request we got from the S-PEPS and for which we have to ask our APs
+ * @param resp the response to the preceding request
+ * @param oaParam the oa param
+ * @throws MOAIDException the mOAID exception
+ */
+ public abstract void performRedirect(String url, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException;
+
+ /**
+ * Parses the response we got from the external attribute provider.
+ *
+ * @param httpReq the http req
+ * @return a list of attributes
+ * @throws UnsupportedAttributeException if the provider cannot find anything familiar in the provided httpReq
+ * @throws MOAIDException if something went wrong
+ */
+ public abstract IPersonalAttributeList parse(HttpServletRequest httpReq) throws UnsupportedAttributeException, MOAIDException;
+
+ /**
+ * Returns the list of supported attributes
+ *
+ * @return a list of attributes
+ * @throws MOAIDException if something went wrong
+ */
+ public List<String> getSupportedAttributeNames() throws MOAIDException {
+ ArrayList<String> supportedAttributeNames = new ArrayList<String>();
+ for (String attributeName : this.attributes.split(",")) {
+ supportedAttributeNames.add(attributeName);
+ }
+ return supportedAttributeNames;
+ }
+
+
+ /**
+ * Returns the sequence priority of this attribute provider.
+ * Providers with small numbers are requested first.
+ *
+ * @return a sequence priority of this provider
+ */
+ public abstract int getPriority();
+
+ /**
+ * Compare the sequence priority of two attribute providers
+ * @param o attribute provider
+ * @return 0 if priority is equal
+ * @return -1 if priority if this is higher then from o
+ * @return +1 if priority if o is higher then from this
+ */
+ @Override
+ public int compareTo(AttributeProvider o) {
+ if (this.getPriority() == o.getPriority())
+ return 0;
+
+ if (this.getPriority() < o.getPriority())
+ return -1;
+
+ else
+ return +1;
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/EHvdAttributeProviderPlugin.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/EHvdAttributeProviderPlugin.java
new file mode 100644
index 000000000..bd1576020
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/EHvdAttributeProviderPlugin.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2.attributeproviders;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPConnection;
+import javax.xml.soap.SOAPConnectionFactory;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.soap.SOAPPart;
+
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException;
+import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException;
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.IsHealthCareProfessionalType;
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.ObjectFactory;
+
+/**
+ * Fetches the attribute IsHealthcareProfessional from the BAGDAD SOAP service
+ */
+public class EHvdAttributeProviderPlugin extends AttributeProvider {
+
+ /** The destination. */
+ private Object destination;
+
+ /**
+ * Instantiates a new e hvd attribute provider plugin.
+ *
+ * @param url the service url
+ * @param supportedAttributes
+ */
+ public EHvdAttributeProviderPlugin(String url, String supportedAttributes) {
+ super(supportedAttributes);
+ destination = url;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(eu.stork.peps.auth.commons.PersonalAttribute)
+ */
+ @Override
+ protected IPersonalAttributeList acquire(PersonalAttribute attribute, MOASTORKRequest moastorkRequest, IAuthData authData)
+ throws UnsupportedAttributeException,
+ ExternalAttributeRequestRequiredException, MOAIDException {
+
+ // break when we cannot handle the requested attribute
+ if(!attributes.contains(attribute.getName()))
+ throw new UnsupportedAttributeException();
+
+ try {
+ Logger.debug("initializing SOAP connections...");
+ // create SOAP connection
+ SOAPConnection soapConnection = SOAPConnectionFactory.newInstance().createConnection();
+
+ // assemble SOAP request
+ MessageFactory messageFactory = MessageFactory.newInstance();
+ SOAPMessage requestMessage = messageFactory.createMessage();
+ SOAPPart requestPart = requestMessage.getSOAPPart();
+
+ // (soap 1.1 relevant part. could not find a solution to use soap 1.2 in time.
+ requestMessage.getMimeHeaders().setHeader("SOAPAction", "http://gesundheit.gv.at/BAGDAD/DataAccessService/IsHealthcareProfessional");
+
+ /*
+ Construct SOAP Request Message:
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+ <soap:Body>
+ <IsHealthcareProfessional xmlns="http://gesundheit.gv.at/BAGDAD/DataAccessService">
+ <bPK>string</bPK>
+ </IsHealthcareProfessional>
+ </soap:Body>
+ </soap:Envelope>
+
+ see https://stork.ehealth.gv.at/GDAService.asmx?op=IsHealthcareProfessional
+ */
+
+ // SOAP Envelope
+ SOAPEnvelope envelope = requestPart.getEnvelope();
+
+ // SOAP Body
+ SOAPBody requestBody = envelope.getBody();
+ SOAPElement requestBodyElem = requestBody.addChildElement("IsHealthcareProfessional");
+ requestBodyElem.addAttribute(envelope.createName("xmlns"), "http://gesundheit.gv.at/BAGDAD/DataAccessService");
+
+ SOAPElement requestBodyElem1 = requestBodyElem.addChildElement("bPK");
+
+ //TODO: CHECK: IdentificationValue containts wbPK if MOA-ID is used as VIDP
+ requestBodyElem1.addTextNode(new BPKBuilder().buildBPK(authData.getIdentificationValue(), "GH"));
+
+ requestMessage.saveChanges();
+
+ // perform SOAP call
+ Logger.debug("call...");
+ SOAPMessage responseMessage = soapConnection.call(requestMessage, destination);
+
+ // parse SOAP response
+
+ /*
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+ <soap:Body>
+ <IsHealthcareProfessionalResponse xmlns="http://gesundheit.gv.at/BAGDAD/DataAccessService">
+ <IsHealthcareProfessionalResult>
+ <RequestOK>boolean</RequestOK>
+ <Message>string</Message>
+ <IsHealthcareProfessional>boolean</IsHealthcareProfessional>
+ <NameOfOrganisation>string</NameOfOrganisation>
+ <Type>string</Type>
+ <Specialization>string</Specialization>
+ </IsHealthcareProfessionalResult>
+ </IsHealthcareProfessionalResponse>
+ </soap:Body>
+ </soap:Envelope>
+
+ see https://stork.ehealth.gv.at/GDAService.asmx?op=IsHealthcareProfessional
+ */
+ Logger.debug("call successful. Parse...");
+ SOAPBody responseBody = responseMessage.getSOAPBody();
+
+ // iterate through tree
+ SOAPElement responseElement = (SOAPElement) responseBody.getChildElements().next();
+ SOAPElement resultElement = (SOAPElement) responseElement.getChildElements().next();
+
+ // collect all info in a map
+ Iterator<?> it = resultElement.getChildElements();
+ Map<String, String> collection = new HashMap<String, String>();
+ while (it.hasNext()) {
+ SOAPElement current = (SOAPElement) it.next();
+
+ collection.put(current.getNodeName(), current.getTextContent());
+ }
+
+ // check if there is anything valid in the map
+ if (collection.isEmpty() || collection.size() != 6) {
+ Logger.warn("eHVD returned an unexpected count of values. Expected 6 got " + collection.size());
+ throw new IndexOutOfBoundsException("response attributes not like specified");
+ }
+
+ // - fetch request validity
+ if (collection.get("RequestOK").equals("false")) {
+ Logger.warn("eHVD reported an invalid request. The error message is: " + collection.get("Message"));
+ throw new Exception("eHVD reported an invalid request");
+ }
+
+ PersonalAttribute acquiredAttribute = null;
+
+ if (collection.get("IsHealthcareProfessional").equals("false") || !collection.get("Type").equals("Medical doctor")) {
+ // the citizen is no HCP
+ acquiredAttribute = new PersonalAttribute("isHealthCareProfessional", false, new ArrayList<String>(), AttributeStatusType.NOT_AVAILABLE.value());
+ } else {
+ // go on and parse the data
+ IsHealthCareProfessionalType result = new IsHealthCareProfessionalType();
+
+ // TODO: we do not have any list of possible values yet. Fix as soon as we get some.
+// if (collection.get("Type").equals("Medical doctor"))
+ result.setTypeOfHCP("physician");
+
+ result.setNameOfOrganisation(collection.get("NameOfOrganisation"));
+ //result.setTypeOfOrganisation("Unknown"); // TODO used in previous version, check what to do with this
+
+ result.setAQAA(4);
+
+ final Marshaller m = JAXBContext.newInstance(IsHealthCareProfessionalType.class).createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+
+ StringWriter stringWriter = new StringWriter();
+ m.marshal(new ObjectFactory().createIsHealthCareProfessional(result), stringWriter);
+
+ ArrayList<String> value = new ArrayList<String>();
+ value.add(stringWriter.toString());
+
+ acquiredAttribute = new PersonalAttribute("isHealthCareProfessional", false, value, AttributeStatusType.AVAILABLE.value());
+ }
+
+ // pack and return the result
+ PersonalAttributeList result = new PersonalAttributeList();
+ result.add(acquiredAttribute);
+
+ // add stork id for verification
+ ArrayList<String> value = new ArrayList<String>();
+ value.add(new BPKBuilder().buildStorkeIdentifier(authData.getIdentityLink(), moastorkRequest.getSpCountry()));
+ result.add(new PersonalAttribute("eIdentifier", false, value, AttributeStatusType.AVAILABLE.value()));
+
+ return result;
+ } catch (Exception e) {
+ throw new MOAIDException("stork.13", new Object[] { e });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.config.auth.OAAuthParameter)
+ */
+ public void performRedirect(String url,
+ HttpServletRequest req, HttpServletResponse resp,
+ OAAuthParameter oaParam) throws MOAIDException {
+ // there is no redirect required
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest)
+ */
+ public IPersonalAttributeList parse(HttpServletRequest httpReq)
+ throws UnsupportedAttributeException, MOAIDException {
+ // there is no redirect required, so we throw an exception when someone asks us to parse a response
+ throw new UnsupportedAttributeException();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#getPriority()
+ */
+ @Override
+ public int getPriority() {
+ return 99;
+ }
+
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java
new file mode 100644
index 000000000..f671f0807
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2.attributeproviders;
+
+import java.io.StringWriter;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException;
+import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+/**
+ * Provides mandate attribute from MIS
+ */
+public class MandateAttributeRequestProvider extends AttributeProvider {
+ /**
+ * The destination.
+ */
+ private String destination;
+
+ private String spCountryCode;
+
+ private PersonalAttributeList requestedAttributes;
+
+ public MandateAttributeRequestProvider(String aPurl, String supportedAttributes) throws MOAIDException {
+ super(supportedAttributes);
+ destination = aPurl;
+
+ }
+
+ public String getAttrProviderName() {
+ return "MandateAttributeRequestProvider";
+ }
+
+ // TODO check if used
+ @Override
+ protected IPersonalAttributeList acquire(PersonalAttribute attribute, MOASTORKRequest moastorkRequest, IAuthData authData) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException, MOAIDException {
+ Logger.info("Acquiring attribute: " + attribute.getName() + ", by: " + getAttrProviderName());
+ this.spCountryCode = moastorkRequest.getSpCountry();
+ requestedAttributes = new PersonalAttributeList(1);
+ requestedAttributes.add(attribute);
+
+ // break if we cannot handle the requested attribute
+ if (!attributes.contains(attribute.getName())) {
+ Logger.info("Attribute " + attribute.getName() + " not supported by the provider: " + getAttrProviderName());
+ throw new UnsupportedAttributeException();
+ }
+
+ // check if there is eIdentifier included and add if necessary
+// if (!requestedAttributes.containsKey("eIdentifier")) {
+// PersonalAttribute eIdentifier = new PersonalAttribute();
+ // eIdentifier.setName("eIdentifier");
+// eIdentifier.setIsRequired(true);
+// requestedAttributes.add(eIdentifier);
+// }
+
+ Logger.info("Thrown external request by: " + getAttrProviderName());
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+ @Override
+ public IPersonalAttributeList acquire(List<PersonalAttribute> attributes, MOASTORKRequest moastorkRequest, IAuthData moasession) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException, MOAIDException {
+ Logger.info("Acquiring " + attributes.size() + " attributes, by: " + getAttrProviderName());
+ this.spCountryCode = moastorkRequest.getSpCountry();
+ requestedAttributes = new PersonalAttributeList(attributes.size());
+
+ for (PersonalAttribute personalAttribute : attributes) {
+ // break if we cannot handle the requested attribute
+ if (!this.attributes.contains(personalAttribute.getName())) {
+ Logger.info("Attribute " + personalAttribute.getName() + " not supported by the provider: " + getAttrProviderName());
+ throw new UnsupportedAttributeException();
+ }
+ requestedAttributes.add(personalAttribute);
+ }
+
+ // continue with other attribute providers if there are no attributes current provider is able to handle
+ if (requestedAttributes.size() == 0) {
+ Logger.info("Attribute(s) " + attributes.toString() + " not supported by the provider: " + getAttrProviderName());
+ throw new UnsupportedAttributeException();
+ }
+
+
+
+ Logger.info("Thrown external request by: " + getAttrProviderName());
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+
+
+
+ public void performRedirect(String url, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException {
+
+ String spSector = "Business";
+ String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName();
+ String spApplication = spInstitution;
+
+ if ((spCountryCode == null) || (spCountryCode.length()<2)) {
+ spCountryCode = oaParam.getTarget();
+ Logger.info("Setting spcountry target: " + oaParam.getTarget());
+ Logger.info("idlink ident " + oaParam.getIdentityLinkDomainIdentifier());
+ Logger.info("idlink type " + oaParam.getIdentityLinkDomainIdentifierType());
+ Logger.info("Setting spcountry target friendly : " + oaParam.getTargetFriendlyName());
+ Logger.info("Oatype : " + oaParam.getOaType());
+ Logger.info("puburl : " + oaParam.getPublicURLPrefix());
+ if ("STORK".equals(oaParam.getIdentityLinkDomainIdentifierType())) {
+
+ spCountryCode = oaParam.getIdentityLinkDomainIdentifier().substring(oaParam.getIdentityLinkDomainIdentifier().length()-2);
+ Logger.info("Set to " +spCountryCode);
+ }
+
+ }
+
+ // TODO ensure that other providers request eidentifier
+ // check if there is eIdentifier included and add if necessary
+ if (!requestedAttributes.containsKey("eIdentifier")) {
+ PersonalAttribute eIdentifier = new PersonalAttribute();
+ eIdentifier.setName("eIdentifier");
+ eIdentifier.setIsRequired(true);
+ requestedAttributes.add(eIdentifier);
+ }
+
+ //generate AttrQueryRequest
+ STORKAttrQueryRequest attributeRequest = new STORKAttrQueryRequest();
+ attributeRequest.setDestination(destination);
+ attributeRequest.setAssertionConsumerServiceURL(url);
+ attributeRequest.setIssuer(HTTPUtils.getBaseURL(req));
+ attributeRequest.setQaa(oaParam.getQaaLevel());
+ attributeRequest.setSpInstitution(spInstitution);
+ attributeRequest.setCountry(spCountryCode);
+ attributeRequest.setSpCountry(spCountryCode);
+ attributeRequest.setSpApplication(spApplication);
+ attributeRequest.setSpSector(spSector);
+ attributeRequest.setPersonalAttributeList(requestedAttributes);
+
+ attributeRequest.setCitizenCountryCode("AT");
+ attributeRequest.setQaa(oaParam.getQaaLevel());
+
+ if (attributeRequest.getQaa() == 0 ) {
+ attributeRequest.setQaa(4); // workaround
+ }
+
+
+
+ Logger.info("STORK AttrRequest successfully assembled.");
+
+ STORKSAMLEngine samlEngine = STORKSAMLEngine.getInstance("VIDP");
+ try {
+
+ attributeRequest = samlEngine.generateSTORKAttrQueryRequest(attributeRequest);
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Could not sign STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.00", null);
+ }
+
+ Logger.info("STORK AttrRequest successfully signed!");
+
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/saml2-post-binding-moa.vm");
+ VelocityContext context = new VelocityContext();
+ context.put("SAMLRequest", PEPSUtil.encodeSAMLToken(attributeRequest.getTokenSaml()));
+ context.put("action", destination);
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+
+ resp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+ } catch (Exception e) {
+ Logger.error("Error sending STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.11", null);
+ }
+ Logger.info("STORK AttrRequest successfully rendered!");
+
+ }
+
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) throws UnsupportedAttributeException, MOAIDException {
+ return null; //
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#getPriority()
+ */
+ @Override
+ public int getPriority() {
+ return 99;
+ }
+}
+
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/PVPAuthenticationProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/PVPAuthenticationProvider.java
new file mode 100644
index 000000000..7f06c604b
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/PVPAuthenticationProvider.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2.attributeproviders;
+
+import java.io.StringWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException;
+import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
+import eu.stork.peps.auth.commons.STORKAuthnRequest;
+import eu.stork.peps.auth.commons.STORKAuthnResponse;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class PVPAuthenticationProvider extends AttributeProvider {
+
+ private String destination = null;
+ private MOASTORKRequest moastorkRequest = null;
+
+ /**
+ * @param attributes
+ * @param attributes2
+ */
+ public PVPAuthenticationProvider(String url, String attributes) {
+ super(attributes);
+ this.destination = url;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#acquire(eu.stork.peps.auth.commons.PersonalAttribute, java.lang.String, at.gv.egovernment.moa.id.data.IAuthData)
+ */
+ @Override
+ protected IPersonalAttributeList acquire(PersonalAttribute attribute,
+ MOASTORKRequest moastorkRequest, IAuthData authData)
+ throws UnsupportedAttributeException,
+ ExternalAttributeRequestRequiredException, MOAIDException {
+
+ this.moastorkRequest = moastorkRequest;
+ // break if we cannot handle the requested attribute
+ if (!getSupportedAttributeNames().contains(attribute.getName())) {
+ Logger.info("Attribute " + attribute.getName() + " not supported by the provider: " + getAttrProviderName());
+ throw new UnsupportedAttributeException();
+
+ }
+
+ Logger.info("Thrown external request by: " + getAttrProviderName());
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#performRedirect(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.config.auth.OAAuthParameter)
+ */
+ @Override
+ public void performRedirect(String url, HttpServletRequest req,
+ HttpServletResponse resp, OAAuthParameter oaParam)
+ throws MOAIDException {
+
+ String spSector = "Business";
+ String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName();
+ String spApplication = spInstitution;
+ String spCountryCode = moastorkRequest.getSpCountry();
+
+ if ((spCountryCode == null) || (spCountryCode.length()<2)) {
+ spCountryCode = oaParam.getTarget();
+ Logger.info("Setting spcountry target: " + oaParam.getTarget());
+ Logger.info("idlink ident " + oaParam.getIdentityLinkDomainIdentifier());
+ Logger.info("idlink type " + oaParam.getIdentityLinkDomainIdentifierType());
+ Logger.info("Setting spcountry target friendly : " + oaParam.getTargetFriendlyName());
+ Logger.info("Oatype : " + oaParam.getOaType());
+ Logger.info("puburl : " + oaParam.getPublicURLPrefix());
+ if ("STORK".equals(oaParam.getIdentityLinkDomainIdentifierType())) {
+
+ spCountryCode = oaParam.getIdentityLinkDomainIdentifier().substring(oaParam.getIdentityLinkDomainIdentifier().length()-2);
+ Logger.info("Set to " +spCountryCode);
+ }
+
+ }
+
+ //generate AttrQueryRequest
+ STORKAuthnRequest authRequest = new STORKAuthnRequest();
+ authRequest.setDestination(destination);
+ authRequest.setAssertionConsumerServiceURL(url);
+ authRequest.setIssuer(HTTPUtils.getBaseURL(req));
+ authRequest.setQaa(oaParam.getQaaLevel());
+ authRequest.setSpInstitution(spInstitution);
+ authRequest.setCountry(spCountryCode);
+ authRequest.setSpCountry(spCountryCode);
+ authRequest.setSpApplication(spApplication);
+ authRequest.setProviderName(spApplication);
+ authRequest.setSpSector(spSector);
+ authRequest.setPersonalAttributeList(moastorkRequest.getPersonalAttributeList());
+
+ authRequest.setCitizenCountryCode("AT");
+ //authRequest.setQaa(oaParam.getQaaLevel());
+ authRequest.setQaa(moastorkRequest.getStorkAuthnRequest().getQaa());
+
+
+
+
+ Logger.info("STORK AttrRequest successfully assembled.");
+
+ STORKSAMLEngine samlEngine = STORKSAMLEngine.getInstance("VIDP");
+ try {
+
+ authRequest = samlEngine.generateSTORKAuthnRequest(authRequest);
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Could not sign STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.00", null);
+ }
+
+ Logger.info("STORK AttrRequest successfully signed!");
+
+ //validate AuthnRequest
+ try {
+ samlEngine.validateSTORKAuthnRequest(authRequest.getTokenSaml());
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("STORK SAML AuthnRequest not valid.", e);
+ throw new MOAIDException("stork.01", null);
+ }
+
+ Logger.debug("STORK AuthnRequest successfully internally validated.");
+
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/saml2-post-binding-moa.vm");
+ VelocityContext context = new VelocityContext();
+ context.put("SAMLRequest", PEPSUtil.encodeSAMLToken(authRequest.getTokenSaml()));
+ context.put("action", destination);
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+
+ resp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+
+ } catch (Exception e) {
+ Logger.error("Error sending STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.11", null);
+
+ }
+ Logger.info("STORK AttrRequest successfully rendered!");
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#parse(javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public IPersonalAttributeList parse(HttpServletRequest httpReq)
+ throws UnsupportedAttributeException, MOAIDException {
+
+ throw new UnsupportedAttributeException();
+
+// Logger.info(this.getClass().getSimpleName() + " tries to extract SAMLResponse out of HTTP Request");
+// //extract STORK Response from HTTP Request
+// //Decodes SAML Response
+// byte[] decSamlToken;
+// try {
+// decSamlToken = PEPSUtil.decodeSAMLToken(httpReq.getParameter("SAMLResponse"));
+// } catch(NullPointerException e) {
+// throw new UnsupportedAttributeException();
+// }
+//
+// //Get SAMLEngine instance
+// STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+//
+// STORKAuthnResponse authnResponse = null;
+// try {
+// //validate SAML Token
+// Logger.debug("Starting validation of SAML response");
+// authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) httpReq.getRemoteHost());
+// Logger.info("SAML response successfully verified!");
+//
+// }catch(STORKSAMLEngineException e){
+// Logger.error("Failed to verify STORK SAML Response", e);
+// throw new MOAIDException("stork.05", null);
+// }
+//
+// return authnResponse.getPersonalAttributeList();
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#getPriority()
+ */
+ @Override
+ public int getPriority() {
+ return 1;
+ }
+
+ public String getAttrProviderName() {
+ return this.getClass().getName();
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/SignedDocAttributeRequestProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/SignedDocAttributeRequestProvider.java
new file mode 100644
index 000000000..def89d0d9
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/SignedDocAttributeRequestProvider.java
@@ -0,0 +1,688 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2.attributeproviders;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.activation.DataSource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Service;
+import javax.xml.ws.soap.SOAPBinding;
+import javax.xml.ws.BindingProvider;
+
+import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException;
+import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import eu.stork.oasisdss.api.ApiUtils;
+import eu.stork.oasisdss.api.LightweightSourceResolver;
+import eu.stork.oasisdss.api.ResultMajor;
+import eu.stork.oasisdss.api.exceptions.ApiUtilsException;
+import eu.stork.oasisdss.profile.AnyType;
+import eu.stork.oasisdss.profile.Base64Data;
+import eu.stork.oasisdss.profile.DocumentType;
+import eu.stork.oasisdss.profile.DocumentWithSignature;
+import eu.stork.oasisdss.profile.IncludeObject;
+import eu.stork.oasisdss.profile.SignRequest;
+import eu.stork.oasisdss.profile.SignResponse;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+import eu.stork.documentservice.DocumentService;
+/**
+ * Forwards a signedDoc attribute request to the oasis-dss service instance
+ */
+public class SignedDocAttributeRequestProvider extends AttributeProvider {
+
+ private String dtlUrl = null;
+ private PersonalAttribute requestedAttribute;
+
+ /**
+ * The URL of the service listening for the oasis dss webform post request
+ */
+ private String oasisDssWebFormURL;
+
+ /**
+ * Instantiates a new signed doc attribute request provider.
+ *
+ * @param oasisDssWebFormURL
+ * the AP location
+ * @param attributes
+ */
+ public SignedDocAttributeRequestProvider(String oasisDssWebFormURL, String attributes) {
+ super(attributes);
+ this.oasisDssWebFormURL = oasisDssWebFormURL;
+
+ try {
+ AuthConfiguration authConfigurationProvider = AuthConfigurationProviderFactory.getInstance();
+ dtlUrl = authConfigurationProvider.getDocumentServiceUrl();
+ Logger.info ("SignedDocAttributeRequestProvider, using dtlUrl:"+dtlUrl);
+ } catch (Exception e) {
+ dtlUrl = "http://testvidp.buergerkarte.at/DocumentService/DocumentService";
+ e.printStackTrace();
+ Logger.error("Loading documentservice url failed, using default value:"+dtlUrl);
+ }
+
+// Properties props = new Properties();
+// try {
+// props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+// dtlUrl = props.getProperty("docservice.url");
+// } catch (IOException e) {
+// dtlUrl = "http://testvidp.buergerkarte.at/DocumentService/DocumentService";
+// Logger.error("Loading DTL config failed, using default value:"+dtlUrl);
+// e.printStackTrace();
+// }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java
+ * .lang.String)
+ */
+ @Override
+ protected IPersonalAttributeList acquire(PersonalAttribute attribute, MOASTORKRequest moastorkRequest, IAuthData authData) throws UnsupportedAttributeException,
+ ExternalAttributeRequestRequiredException {
+ if(!attributes.contains(attribute.getName())) {
+ throw new UnsupportedAttributeException();
+ }
+
+ requestedAttribute = attribute;
+ try
+ {
+ String tmp = requestedAttribute.getValue().get(0);
+ }catch(Exception e)
+ {
+ Logger.info("SignedDocAttributeProvide failed:"+e.toString());
+ throw new UnsupportedAttributeException();
+ }
+
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax
+ * .servlet.http.HttpServletRequest)
+ */
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) throws MOAIDException, UnsupportedAttributeException {
+ Logger.debug("Beginning to extract OASIS-DSS response out of HTTP Request");
+
+ try {
+ String base64 = httpReq.getParameter("signresponse");
+ Logger.debug("signresponse url: " + httpReq.getRequestURI().toString());
+ Logger.debug("signresponse querystring: " + httpReq.getQueryString());
+ Logger.debug("signresponse method: " + httpReq.getMethod());
+ Logger.debug("signresponse content type: " + httpReq.getContentType());
+ Logger.debug("signresponse parameter:"+base64);
+ String signResponseString = new String(Base64Utils.decode(base64, false), "UTF8");
+ Logger.debug("RECEIVED signresponse:"+signResponseString);
+ //create SignResponse object
+ Source response = new StreamSource(new java.io.StringReader(signResponseString));
+ SignResponse signResponse = ApiUtils.unmarshal(response, SignResponse.class);
+ //Check if Signing was successfully or not
+
+ if(!signResponse.getResult().getResultMajor().equals(ResultMajor.RESULT_MAJOR_SUCCESS))
+ {
+ //Pass unmodifed or unmarshal & marshal??
+ InputStream istr = ApiUtils.marshalToInputStream(signResponse);
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(istr, writer, "UTF-8");
+ signResponseString = writer.toString();
+ Logger.info("SignResponse with error (unmodified):"+signResponseString);
+ istr.close();
+ }
+ else
+ {
+ //extract doc from signresponse
+ DataSource dataSource = LightweightSourceResolver.getDataSource(signResponse);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ IOUtils.copy(dataSource.getInputStream(), baos);
+ byte[] data = baos.toByteArray();
+ baos.close();
+
+ //update doc in DTL
+ String docId, dssId = "";
+ docId = signResponse.getDocUI();
+ //For reference dssId equals docId
+ dssId = docId;
+ if (dssId != null && data!=null)
+ {
+ boolean success = false;
+ try{
+ success = updateDocumentInDtl(data, docId, signResponseString);
+ }catch(Exception e){//No document service used?
+ Logger.info("No document service used?");
+ e.printStackTrace();
+ success = false;
+ }
+ if(success)
+ {
+ // set the url in the SignResponse
+ DocumentWithSignature documentWithSignature = new DocumentWithSignature();
+ DocumentType value = new DocumentType();
+ if(dtlUrl.endsWith("?wsdl"))
+ {
+ String tmp = dtlUrl.replace("?wsdl", "");
+ Logger.debug("DocumentUrl ends with ? wsdl, using "+tmp+" instead.");
+ value.setDocumentURL(tmp);
+ }
+ else
+ {
+ value.setDocumentURL(dtlUrl);
+ }
+ documentWithSignature.setDocument(value);
+ if(signResponse.getOptionalOutputs()!=null)
+ {
+ //signResponse.getOptionalOutputs().getAny().add(documentWithSignature);
+ for(Object o :signResponse.getOptionalOutputs().getAny())
+ {
+ if(o instanceof DocumentWithSignature)
+ {
+ signResponse.getOptionalOutputs().getAny().remove(o);
+ signResponse.getOptionalOutputs().getAny().add(documentWithSignature);
+ break;
+ }
+ }
+ }
+ else
+ {
+ AnyType anytype = new AnyType();
+ anytype.getAny().add(documentWithSignature);
+ signResponse.setOptionalOutputs(anytype );
+ }
+
+ // System.out.println("overwriting:"+signResponse.getResult().getResultMessage()+" with DTL url:"+dtlUrl);
+ InputStream istr = ApiUtils.marshalToInputStream(signResponse);
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(istr, writer, "UTF-8");
+ signResponseString = writer.toString();
+ Logger.info("SignResponse overwritten:"+signResponseString);
+ istr.close();
+ }
+ else
+ {
+ //No document service used?
+ // do nothing....
+ //TODO temporary fix because document is deleted after fetching => SP can't download Doc
+ //Add doc to Signresponse
+
+ DocumentWithSignature documentWithSignature = new DocumentWithSignature();
+ DocumentType value = new DocumentType();
+ if(signResponse.getProfile().toLowerCase().contains("xades"))
+ {
+ value.setBase64XML(data);
+ }
+ else
+ {
+ Base64Data base64data = new Base64Data();
+ base64data.setValue(data);
+ base64data.setMimeType(dataSource.getContentType());
+ value.setBase64Data(base64data);
+ }
+ documentWithSignature.setDocument(value);
+ if(signResponse.getOptionalOutputs()!=null)
+ {
+ //signResponse.getOptionalOutputs().getAny().add(documentWithSignature);
+ for(Object o :signResponse.getOptionalOutputs().getAny())
+ {
+ if(o instanceof DocumentWithSignature)
+ {
+ signResponse.getOptionalOutputs().getAny().remove(o);
+ signResponse.getOptionalOutputs().getAny().add(documentWithSignature);
+ break;
+ }
+ }
+ }
+ else
+ {
+ AnyType anytype = new AnyType();
+ anytype.getAny().add(documentWithSignature);
+ signResponse.setOptionalOutputs(anytype );
+ }
+
+ // System.out.println("overwriting:"+signResponse.getResult().getResultMessage()+" with DTL url:"+dtlUrl);
+ InputStream istr = ApiUtils.marshalToInputStream(signResponse);
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(istr, writer, "UTF-8");
+ signResponseString = writer.toString();
+ Logger.info("SignResponse overwritten:"+signResponseString);
+ istr.close();
+ }
+ }
+ else
+ throw new Exception("No DSS id found.");
+ }
+
+ //alter signresponse
+ //done
+ List<String> values = new ArrayList<String>();
+ values.add(signResponseString);
+
+ Logger.debug("Assembling signedDoc attribute");
+ PersonalAttribute signedDocAttribute = new PersonalAttribute("signedDoc", false, values,
+ AttributeStatusType.AVAILABLE.value());
+
+ // pack and return the result
+ PersonalAttributeList result = new PersonalAttributeList();
+ result.add(signedDocAttribute);
+ return result;
+ } catch (UnsupportedEncodingException e) {
+ Logger.error("Failed to assemble signedDoc attribute");
+ throw new MOAIDException("stork.05", null);
+ } catch (ApiUtilsException e) {
+ e.printStackTrace();
+ Logger.error("Failed to assemble signedDoc attribute");
+ throw new MOAIDException("stork.05", null);
+ } catch (IOException e) {
+ e.printStackTrace();
+ Logger.error("Failed to assemble signedDoc attribute");
+ throw new MOAIDException("stork.05", null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Logger.error("Failed to assemble signedDoc attribute");
+ //throw new MOAIDException("stork.05", null);
+ throw new UnsupportedAttributeException();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect
+ * (java.lang.String)
+ */
+ public void performRedirect(String url, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam)
+ throws MOAIDException {
+
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+ Logger.info("performRedirect url:"+url);
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/oasis_dss_webform_binding.vm");
+ VelocityContext context = new VelocityContext();
+
+ //Parse SignRequest
+ String signRequestString = requestedAttribute.getValue().get(0);
+ Logger.debug("performRedirect, signrequest:"+signRequestString);
+ Source signDoc = new StreamSource(new java.io.StringReader(signRequestString));
+ SignRequest signRequest = ApiUtils.unmarshal(signDoc, SignRequest.class);
+ try{
+ //search for DTL link
+ String dtlURL = getDtlUrlFromRequest(signRequest);
+ String docId = signRequest.getDocUI();
+
+ if(dtlURL!=null)
+ {
+ String docRequest = getDocTransferRequest(docId, dtlURL);//dtlUrl
+
+ byte[] data = getDocumentFromDtl(docRequest, dtlURL);//dtlUrl
+
+ //load doc from DTL
+ Logger.debug("data:"+data+" "+data.length);
+ try{
+ Logger.trace("data:"+new String(data,"UTF-8"));
+ }catch(Exception e)
+ {
+ Logger.trace("data: creating String failed:"+e);
+ }
+ String mime = getDocumentMimeFromDtl(docId, dtlURL);//dtlUrl
+ Logger.debug("mime:"+mime);
+
+ //add doc as base64* to signrequest => post doc to oasis
+ try{
+ List<IncludeObject> includeObjects = ApiUtils.findNamedElement(
+ signRequest.getOptionalInputs(), "IncludeObject",
+ IncludeObject.class);
+ signRequest.getOptionalInputs().getAny().removeAll(includeObjects);
+
+ String documentId = null;
+ Object objDoc = signRequest.getInputDocuments().getDocumentOrTransformedDataOrDocumentHash().get(0);
+ if (objDoc != null && objDoc instanceof DocumentType)
+ {
+ DocumentType document = (DocumentType)objDoc;
+ documentId = document.getID();
+ }
+ DocumentType document = new DocumentType();
+ if(documentId != null)
+ document.setID(documentId);
+ if(signRequest.getProfile().toLowerCase().contains("xades"))
+ {
+ document.setBase64XML(data);
+ }
+ else
+ {
+ Base64Data b64data = new Base64Data();
+ b64data.setValue(data);
+ b64data.setMimeType(mime);
+ document.setBase64Data(b64data);
+ }
+
+ signRequest.setInputDocuments(ApiUtils.createInputDocuments(document));
+ //override old signRequestString
+
+ InputStream istr = ApiUtils.marshalToInputStream(signRequest);
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(istr, writer, "UTF-8");
+ signRequestString = writer.toString();
+ Logger.info("Signrequest overwritten");
+ Logger.debug("Signrequest overwritten:"+signRequestString);
+ istr.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new Exception("Could not marshall sign request", e);
+ }
+ }
+ else//Do not modify signRequest, document is already included
+ {
+
+ }
+ }catch(Exception e)
+ {
+ Logger.info("No documentservice used?");
+ e.printStackTrace();
+ }
+
+ context.put("signrequest", Base64Utils.encode(signRequestString.getBytes("UTF8")));
+ context.put("clienturl", url);
+ context.put("action", oasisDssWebFormURL);
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+
+ resp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+ } catch (Exception e) {
+ Logger.error("Error sending DSS signrequest.", e);
+ throw new MOAIDException("stork.11", null);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#getSupportedAttributeNames()
+ */
+ @Override
+ public List<String> getSupportedAttributeNames() throws MOAIDException {
+ ArrayList<String> supportedAttributeNames = new ArrayList<String>();
+ for (String attributeName : this.attributes.split(",")) {
+ supportedAttributeNames.add(attributeName);
+ }
+ return supportedAttributeNames;
+ }
+
+
+ //From DTLPEPSUTIL
+
+ /**
+ * Get DTL uril from the oasis sign request
+ * @param signRequest The signature request
+ * @return The URL of DTL service
+ * @throws SimpleException
+ */
+ private String getDtlUrlFromRequest(SignRequest signRequest) throws Exception
+ {
+ if (signRequest == null)
+ throw new Exception("Signature request is empty");
+ else
+ {
+ try
+ {
+ Object objDoc = signRequest.getInputDocuments().getDocumentOrTransformedDataOrDocumentHash().get(0);
+ if (objDoc instanceof DocumentType)
+ {
+ DocumentType document = (DocumentType)objDoc;
+ if (document.getDocumentURL() != null)
+ return document.getDocumentURL();
+ else
+ return null;//throw new Exception("No document url found");
+ }
+ else
+ throw new Exception("No input document found");
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("Unable to parse xml.", ex);
+ }
+ }
+ }
+
+ /**
+ * Get document from DTL
+ * @param transferRequest The transfer request (attribute query)
+ * @param eDtlUrl The DTL url of external DTL
+ * @return the document data
+ * @throws SimpleException
+ */
+ private byte[] getDocumentFromDtl(String transferRequest, String eDtlUrl) throws Exception
+ {
+ URL url = null;
+ try
+ {
+ Logger.debug("getDocumentFromDtl:"+dtlUrl);
+ url = new URL(dtlUrl);
+ QName qname = new QName("http://stork.eu",
+ "DocumentService");
+
+ Service service = Service.create(url, qname);
+ DocumentService docservice = service.getPort(DocumentService.class);
+
+ BindingProvider bp = (BindingProvider) docservice;
+ SOAPBinding binding = (SOAPBinding) bp.getBinding();
+ binding.setMTOMEnabled(true);
+
+ if (eDtlUrl.equalsIgnoreCase(dtlUrl))
+ return docservice.getDocument(transferRequest, "");
+ else
+ return docservice.getDocument(transferRequest, eDtlUrl);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new Exception("Error in getDocumentFromDtl", e);
+ }
+ }
+
+ /**
+ * Get a document transfer request (attribute query)
+ * @param docId
+ * @return
+ * @throws SimpleException
+ */
+ private String getDocTransferRequest(String docId, String destinationUrl) throws Exception
+ {
+ String spCountry = docId.substring(0, docId.indexOf("/"));
+ final STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+ STORKAttrQueryRequest req = new STORKAttrQueryRequest();
+ req.setAssertionConsumerServiceURL(dtlUrl);
+ req.setDestination(destinationUrl);
+ req.setSpCountry(spCountry);
+ req.setQaa(3);//TODO
+ PersonalAttributeList pal = new PersonalAttributeList();
+ PersonalAttribute attr = new PersonalAttribute();
+ attr.setName("docRequest");
+ attr.setIsRequired(true);
+ attr.setValue(Arrays.asList(docId));
+ pal.add(attr);
+ req.setPersonalAttributeList(pal);
+
+ STORKAttrQueryRequest req1;
+ try {
+ req1 = engine.generateSTORKAttrQueryRequest(req);
+ return PEPSUtil.encodeSAMLTokenUrlSafe(req1.getTokenSaml());
+ } catch (STORKSAMLEngineException e) {
+ e.printStackTrace();
+ throw new Exception("Error in doc request attribute query generation", e);
+ }
+ }
+
+ /**
+ * Get mime type of document from DTL
+ * @param docId The document id
+ * @param dtlUrl The url of dtl
+ * @return The mime type
+ */
+ private String getDocumentMimeFromDtl(String docId, String eDtlUrl) throws Exception
+ {
+ URL url = null;
+ try
+ {
+ url = new URL(dtlUrl);
+ QName qname = new QName("http://stork.eu",
+ "DocumentService");
+
+ Service service = Service.create(url, qname);
+ DocumentService docservice = service.getPort(DocumentService.class);
+
+ BindingProvider bp = (BindingProvider) docservice;
+ SOAPBinding binding = (SOAPBinding) bp.getBinding();
+ binding.setMTOMEnabled(true);
+
+ if (eDtlUrl.equalsIgnoreCase(dtlUrl))
+ return docservice.getDocumentMime(docId, "");
+ else
+ return docservice.getDocumentMime(docId, eDtlUrl);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new Exception("Error in getDocumentFromDtl", e);
+ }
+ }
+
+ /**
+ * Add document to DTL service
+ * @param docData the document data
+ * @param mime the mime type of data
+ * @param signRequest the sign request
+ * @return the document id
+ * @throws SimpleException
+ */
+ private String addDocumentToDtl(byte[] docData, String mime, String signRequest, String destCountry, String spId) throws Exception
+ {
+ throw new NotImplementedException();
+// URL url = null;
+// String docID = null;
+// try
+// {
+// url = new URL(dtlUrl);
+// QName qname = new QName("http://stork.eu",
+// "DocumentService");
+//
+// Service service = Service.create(url, qname);
+// DocumentService docservice = service.getPort(DocumentService.class);
+//
+// BindingProvider bp = (BindingProvider) docservice;
+// SOAPBinding binding = (SOAPBinding) bp.getBinding();
+// binding.setMTOMEnabled(true);
+//
+// docID = docservice.addDocument(docData, signRequest, destCountry, spId, mime, "");
+// }
+// catch (Exception e)
+// {
+// e.printStackTrace();
+// throw new Exception("Error in addDocumentToDtl", e);
+// }
+//
+// return docID;
+ }
+
+ /**
+ * Update document in DTL
+ * @param docData The docment data
+ * @param docId The document ID
+ * @param signResponse The signature response
+ * @return True if successful
+ * @throws SimpleException
+ */
+ private boolean updateDocumentInDtl(byte[] docData, String docId, String signResponse) throws Exception
+ {
+ boolean success = false;
+ URL url = null;
+ try
+ {
+ url = new URL(dtlUrl);
+ QName qname = new QName("http://stork.eu",
+ "DocumentService");
+
+ Service service = Service.create(url, qname);
+ DocumentService docservice = service.getPort(DocumentService.class);
+
+ BindingProvider bp = (BindingProvider) docservice;
+ SOAPBinding binding = (SOAPBinding) bp.getBinding();
+ binding.setMTOMEnabled(true);
+
+ success = docservice.updateDocument(docId, signResponse, docData);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new Exception("Error in updateDocumentInDtl", e);
+ }
+
+ return success;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#getPriority()
+ */
+ @Override
+ public int getPriority() {
+ return 99;
+ }
+}
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/StorkAttributeRequestProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/StorkAttributeRequestProvider.java
new file mode 100644
index 000000000..5ee0e380e
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/StorkAttributeRequestProvider.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 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:
+ * http://www.osor.eu/eupl/
+ *
+ * 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.egovernment.moa.id.protocols.stork2.attributeproviders;
+
+import java.io.StringWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException;
+import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
+import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+/**
+ * creates a STORK attribute request for a configurable set of attributes
+ */
+public class StorkAttributeRequestProvider extends AttributeProvider {
+
+ private PersonalAttributeList requestedAttributes;
+
+ /** The destination. */
+ private String destination;
+
+ /** The sp country code. */
+ private String spCountryCode;
+
+ /**
+ * Instantiates a new stork attribute request provider.
+ *
+ * @param apUrl the AP location
+ * @param supportedAttributes the supported attributes as csv
+ */
+ public StorkAttributeRequestProvider(String apUrl, String supportedAttributes) {
+ super(supportedAttributes);
+ destination = apUrl;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String)
+ */
+ @Override
+ protected IPersonalAttributeList acquire(PersonalAttribute attribute, MOASTORKRequest moastorkRequest, IAuthData authData)
+ throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException {
+
+ if (!attributes.contains(attribute.getName()))
+ throw new UnsupportedAttributeException();
+
+ this.spCountryCode = moastorkRequest.getSpCountry();
+
+ requestedAttributes = new PersonalAttributeList(1);
+ requestedAttributes.add(attribute);
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest)
+ */
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) throws MOAIDException, UnsupportedAttributeException {
+
+ Logger.info(this.getClass().getSimpleName() + " tries to extract SAMLResponse out of HTTP Request");
+
+ //extract STORK Response from HTTP Request
+ //Decodes SAML Response
+ byte[] decSamlToken;
+ try {
+ decSamlToken = PEPSUtil.decodeSAMLToken(httpReq.getParameter("SAMLResponse"));
+ } catch(NullPointerException e) {
+ throw new UnsupportedAttributeException();
+ }
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+
+ STORKAttrQueryResponse attrResponse = null;
+ try {
+ //validate SAML Token
+ Logger.debug("Starting validation of SAML response");
+ attrResponse = engine.validateSTORKAttrQueryResponse(decSamlToken, (String) httpReq.getRemoteHost());
+ Logger.info("SAML response successfully verified!");
+ }catch(STORKSAMLEngineException e){
+ Logger.error("Failed to verify STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ return attrResponse.getPersonalAttributeList();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String)
+ */
+ public void performRedirect(String url, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException {
+
+ String spSector = "Business";
+ String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName();
+ String spApplication = spInstitution;
+
+ //generate AuthnRquest
+ STORKAttrQueryRequest attributeRequest = new STORKAttrQueryRequest();
+ attributeRequest.setDestination(destination);
+ attributeRequest.setAssertionConsumerServiceURL(url);
+ attributeRequest.setIssuer(HTTPUtils.getBaseURL(req));
+ attributeRequest.setQaa(oaParam.getQaaLevel());
+ attributeRequest.setSpInstitution(spInstitution);
+ attributeRequest.setCountry(spCountryCode);
+ attributeRequest.setSpCountry(spCountryCode);
+ attributeRequest.setSpApplication(spApplication);
+ attributeRequest.setSpSector(spSector);
+ attributeRequest.setPersonalAttributeList(requestedAttributes);
+
+ attributeRequest.setCitizenCountryCode("AT");
+
+
+ Logger.debug("STORK AttrRequest successfully assembled.");
+
+ STORKSAMLEngine samlEngine = STORKSAMLEngine.getInstance("VIDP");
+ try {
+ attributeRequest = samlEngine.generateSTORKAttrQueryRequest(attributeRequest);
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Could not sign STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.00", null);
+ }
+ Logger.info("Using citizen country code: " + attributeRequest.getCitizenCountryCode());
+ Logger.info("STORK AttrRequest successfully signed!");
+
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/saml2-post-binding-moa.vm");
+ VelocityContext context = new VelocityContext();
+ context.put("SAMLRequest", PEPSUtil.encodeSAMLToken(attributeRequest.getTokenSaml()));
+ context.put("action", destination);
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+
+ resp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+ } catch (Exception e) {
+ Logger.error("Error sending STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.11", null);
+ }
+ Logger.info("STORK AttrRequest successfully rendered!");
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#getPriority()
+ */
+ @Override
+ public int getPriority() {
+ return 99;
+ }
+
+}
+
diff --git a/id/server/modules/module-stork/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo b/id/server/modules/module-stork/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo
new file mode 100644
index 000000000..5d7af87d5
--- /dev/null
+++ b/id/server/modules/module-stork/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo
@@ -0,0 +1 @@
+at.gv.egovernment.moa.id.protocols.stork2.STORKProtocol \ No newline at end of file
diff --git a/id/server/modules/pom.xml b/id/server/modules/pom.xml
index 1ca5b3835..fcba9428b 100644
--- a/id/server/modules/pom.xml
+++ b/id/server/modules/pom.xml
@@ -22,6 +22,8 @@
<modules>
<module>module-stork</module>
<module>module-monitoring</module>
+ <module>moa-id-modules-saml1</module>
+ <module>moa-id-module-openID</module>
</modules>
<dependencies>