summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_idp/src
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_idp/src')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java54
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java48
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java62
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java76
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java55
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java58
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java70
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java50
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java46
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java40
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java35
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java59
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java549
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java299
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java203
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java69
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java62
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java328
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java459
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java469
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider2
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml35
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java226
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java156
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java67
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java56
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java25
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java52
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java16
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java18
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props12
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props12
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/Assertion_1.xml46
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/AuthRequest_without_sig_1.xml11
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/junit.jksbin0 -> 2733 bytes
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml126
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml31
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml48
38 files changed, 2728 insertions, 1302 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java
deleted file mode 100644
index d50c5ee4..00000000
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/PVP2SProfileIDPSpringResourceProvider.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.modules.pvp2.idp;
-
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-
-import at.gv.egiz.components.spring.api.SpringResourceProvider;
-
-public class PVP2SProfileIDPSpringResourceProvider implements SpringResourceProvider {
-
- @Override
- public String getName() {
- return "EAAF PVP2 S-Profile IDP SpringResourceProvider";
- }
-
- @Override
- public String[] getPackagesToScan() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Resource[] getResourcesToLoad() {
- ClassPathResource sl20AuthConfig = new ClassPathResource("/eaaf_pvp_idp.beans.xml", PVP2SProfileIDPSpringResourceProvider.class);
-
- return new Resource[] {sl20AuthConfig};
- }
-
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java
new file mode 100644
index 00000000..7e572d70
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/Pvp2SProfileIdpSpringResourceProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.idp;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+public class Pvp2SProfileIdpSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public String getName() {
+ return "EAAF PVP2 S-Profile IDP SpringResourceProvider";
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ final ClassPathResource sl20AuthConfig = new ClassPathResource("/eaaf_pvp_idp.beans.xml",
+ Pvp2SProfileIdpSpringResourceProvider.class);
+
+ return new Resource[] { sl20AuthConfig };
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java
index 90662f48..fd04e38f 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/api/builder/ISubjectNameIdGenerator.java
@@ -1,45 +1,39 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.api.builder;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.impl.data.Pair;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
public interface ISubjectNameIdGenerator {
- /**
- * Generates a SAML2 subjectNameId from authentication data
- *
- * @param authData Authentication data for the current pending request
- * @param spConfig Service provider configuration
- * @return Pair of subjectNameId and NameIdFormat
- * @throws PVP2Exception
- */
- public Pair<String, String> generateSubjectNameId(IAuthData authData, ISPConfiguration spConfig) throws PVP2Exception;
+ /**
+ * Generates a SAML2 subjectNameId from authentication data.
+ *
+ * @param authData Authentication data for the current pending request
+ * @param spConfig Service provider configuration
+ * @return Pair of subjectNameId and NameIdFormat
+ * @throws Pvp2Exception In case of an error
+ */
+ Pair<String, String> generateSubjectNameId(IAuthData authData, ISpConfiguration spConfig)
+ throws Pvp2Exception;
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java
index 42424726..a7e05664 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionConsumerServiceException.java
@@ -1,54 +1,46 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-import org.opensaml.saml2.core.StatusCode;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+
+import org.opensaml.saml.saml2.core.StatusCode;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+public class InvalidAssertionConsumerServiceException extends Pvp2Exception {
-public class InvalidAssertionConsumerServiceException extends PVP2Exception {
+ private static final long serialVersionUID = 7861790149343943091L;
- public InvalidAssertionConsumerServiceException(int idx) {
- super("pvp2.28", new Object[]{idx});
- this.statusCodeValue = StatusCode.REQUESTER_URI;
- }
+ public InvalidAssertionConsumerServiceException(final int idx) {
+ super("pvp2.28", new Object[] { idx });
+ this.statusCodeValue = StatusCode.REQUESTER;
+ }
- /**
- *
- */
- public InvalidAssertionConsumerServiceException(String wrongURL) {
- super("pvp2.23", new Object[]{wrongURL});
- this.statusCodeValue = StatusCode.REQUESTER_URI;
-
- }
+ /**
+ * Invalid assertion consumer-service URL.
+ *
+ * @param wrongUrl invalid URL
+ */
+ public InvalidAssertionConsumerServiceException(final String wrongUrl) {
+ super("pvp2.23", new Object[] { wrongUrl });
+ this.statusCodeValue = StatusCode.REQUESTER;
- /**
- *
- */
- private static final long serialVersionUID = 7861790149343943091L;
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java
index 55c94df1..89179ff6 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/InvalidAssertionEncryptionException.java
@@ -1,42 +1,35 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-import org.opensaml.saml2.core.StatusCode;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+import org.opensaml.saml.saml2.core.StatusCode;
-public class InvalidAssertionEncryptionException extends PVP2Exception {
+public class InvalidAssertionEncryptionException extends Pvp2Exception {
- private static final long serialVersionUID = 6513388841485355549L;
+ private static final long serialVersionUID = 6513388841485355549L;
- public InvalidAssertionEncryptionException() {
- super("pvp2.16", new Object[]{});
- this.statusCodeValue = StatusCode.RESPONDER_URI;
- }
+ public InvalidAssertionEncryptionException() {
+ super("pvp2.16", new Object[] {});
+ this.statusCodeValue = StatusCode.RESPONDER;
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java
index 6109c78d..cf4ac8d1 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/RequestDeniedException.java
@@ -1,45 +1,35 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-import org.opensaml.saml2.core.StatusCode;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+import org.opensaml.saml.saml2.core.StatusCode;
-public class RequestDeniedException extends PVP2Exception {
+public class RequestDeniedException extends Pvp2Exception {
- public RequestDeniedException() {
- super("pvp2.14", null);
- this.statusCodeValue = StatusCode.REQUEST_DENIED_URI;
- }
+ private static final long serialVersionUID = 4415896615794730553L;
- /**
- *
- */
- private static final long serialVersionUID = 4415896615794730553L;
+ public RequestDeniedException() {
+ super("pvp2.14", null);
+ this.statusCodeValue = StatusCode.REQUEST_DENIED;
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java
index 7f565c00..e6cdf8f1 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/ResponderErrorException.java
@@ -1,50 +1,40 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-import org.opensaml.saml2.core.StatusCode;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+
+import org.opensaml.saml.saml2.core.StatusCode;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+public class ResponderErrorException extends Pvp2Exception {
-public class ResponderErrorException extends PVP2Exception {
+ private static final long serialVersionUID = -425416760138285446L;
- /**
- *
- */
- private static final long serialVersionUID = -425416760138285446L;
+ public ResponderErrorException(final String messageId, final Object[] parameters,
+ final Throwable wrapped) {
+ super(messageId, parameters, wrapped);
+ this.statusCodeValue = StatusCode.RESPONDER;
+ }
- public ResponderErrorException(String messageId, Object[] parameters,
- Throwable wrapped) {
- super(messageId, parameters, wrapped);
- this.statusCodeValue = StatusCode.RESPONDER_URI;
- }
-
- public ResponderErrorException(String messageId, Object[] parameters) {
- super(messageId, parameters);
- this.statusCodeValue = StatusCode.RESPONDER_URI;
- }
+ public ResponderErrorException(final String messageId, final Object[] parameters) {
+ super(messageId, parameters);
+ this.statusCodeValue = StatusCode.RESPONDER;
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java
deleted file mode 100644
index a0fad363..00000000
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSignedException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-
-import org.opensaml.saml2.core.StatusCode;
-
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
-
-public class SAMLRequestNotSignedException extends PVP2Exception {
-
- public SAMLRequestNotSignedException() {
- super("pvp2.07", null);
- this.statusCodeValue = StatusCode.REQUESTER_URI;
- }
-
- public SAMLRequestNotSignedException(Throwable e) {
- super("pvp2.07", null, e);
- this.statusCodeValue = StatusCode.REQUESTER_URI;
- }
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java
deleted file mode 100644
index e59ebe0a..00000000
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SAMLRequestNotSupported.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-
-import org.opensaml.saml2.core.StatusCode;
-
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
-
-
-public class SAMLRequestNotSupported extends PVP2Exception {
-
- public SAMLRequestNotSupported() {
- super("pvp2.09", null);
- this.statusCodeValue = StatusCode.REQUEST_UNSUPPORTED_URI;
- }
-
- /**
- *
- */
- private static final long serialVersionUID = 1244883178458802767L;
-
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java
new file mode 100644
index 00000000..add2103b
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSignedException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
+
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+
+import org.opensaml.saml.saml2.core.StatusCode;
+
+public class SamlRequestNotSignedException extends Pvp2Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public SamlRequestNotSignedException() {
+ super("pvp2.07", null);
+ this.statusCodeValue = StatusCode.REQUESTER;
+ }
+
+ public SamlRequestNotSignedException(final Throwable e) {
+ super("pvp2.07", null, e);
+ this.statusCodeValue = StatusCode.REQUESTER;
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java
new file mode 100644
index 00000000..d672f457
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/SamlRequestNotSupported.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
+
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+
+import org.opensaml.saml.saml2.core.StatusCode;
+
+public class SamlRequestNotSupported extends Pvp2Exception {
+
+ private static final long serialVersionUID = 1244883178458802767L;
+
+ public SamlRequestNotSupported() {
+ super("pvp2.09", null);
+ this.statusCodeValue = StatusCode.REQUEST_UNSUPPORTED;
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java
index 0dfda55f..3a56b414 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/exception/UnprovideableAttributeException.java
@@ -1,43 +1,34 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.exception;
-import org.opensaml.saml2.core.StatusCode;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+
+import org.opensaml.saml.saml2.core.StatusCode;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+public class UnprovideableAttributeException extends Pvp2Exception {
-public class UnprovideableAttributeException extends PVP2Exception {
- /**
- *
- */
- private static final long serialVersionUID = 3972197758163647157L;
+ private static final long serialVersionUID = 3972197758163647157L;
- public UnprovideableAttributeException(String attributeName) {
- super("pvp2.10", new Object[] {attributeName});
- this.statusCodeValue = StatusCode.UNKNOWN_ATTR_PROFILE_URI;
- }
+ public UnprovideableAttributeException(final String attributeName) {
+ super("pvp2.10", new Object[] { attributeName });
+ this.statusCodeValue = StatusCode.UNKNOWN_ATTR_PROFILE;
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java
new file mode 100644
index 00000000..597d3c22
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java
@@ -0,0 +1,549 @@
+/*******************************************************************************
+ * Copyright 2017 Graz University of Technology
+ * EAAF-Core Components has been developed in a cooperation between EGIZ,
+ * A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+/*******************************************************************************
+ *******************************************************************************/
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.modules.pvp2.idp.impl;
+
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.StatusMessage;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.ws.security.SecurityPolicyException;
+import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.signature.SignableXMLObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
+import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.SLOException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController;
+import at.gv.egiz.eaaf.modules.pvp2.PVPEventConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestPostProcessor;
+import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidPVPRequestException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.NameIDFormatNotSupportedException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionConsumerServiceException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PVPSProfileRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EAAFURICompare;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SAMLVerificationEngine;
+
+public abstract class AbstractPVP2XProtocol extends AbstractController implements IModulInfo {
+ private static final Logger log = LoggerFactory.getLogger(AbstractPVP2XProtocol.class);
+
+ @Autowired(required=true) protected IPVP2BasicConfiguration pvpBasicConfiguration;
+ @Autowired(required=true) protected IPVPMetadataProvider metadataProvider;
+ @Autowired(required=true) protected SAMLVerificationEngine samlVerificationEngine;
+ @Autowired(required=false) protected List<IAuthnRequestPostProcessor> authRequestPostProcessors;
+
+ private AbstractCredentialProvider pvpIDPCredentials;
+
+
+
+ /**
+ * Sets a specific credential provider for PVP S-Profile IDP component.
+ * @param pvpIDPCredentials credential provider
+ */
+ public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) {
+ this.pvpIDPCredentials = pvpIDPCredentials;
+
+ }
+
+ public boolean generateErrorMessage(Throwable e,
+ HttpServletRequest request, HttpServletResponse response,
+ IRequest protocolRequest) throws Throwable {
+
+ if(protocolRequest == null) {
+ throw e;
+ }
+
+ if(!(protocolRequest instanceof PVPSProfilePendingRequest) ) {
+ throw e;
+ }
+ PVPSProfilePendingRequest pvpRequest = (PVPSProfilePendingRequest)protocolRequest;
+
+ Response samlResponse =
+ SAML2Utils.createSAMLObject(Response.class);
+ Status status = SAML2Utils.createSAMLObject(Status.class);
+ StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class);
+ StatusMessage statusMessage = SAML2Utils.createSAMLObject(StatusMessage.class);
+
+ String moaError = null;
+
+ if(e instanceof NoPassivAuthenticationException) {
+ statusCode.setValue(StatusCode.NO_PASSIVE_URI);
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
+
+ } else if (e instanceof NameIDFormatNotSupportedException) {
+ statusCode.setValue(StatusCode.INVALID_NAMEID_POLICY_URI);
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
+
+ } else if (e instanceof SLOException) {
+ //SLOExecpetions only occurs if session information is lost
+ return false;
+
+ } else if(e instanceof PVP2Exception) {
+ PVP2Exception ex = (PVP2Exception) e;
+ statusCode.setValue(ex.getStatusCodeValue());
+ String statusMessageValue = ex.getStatusMessageValue();
+ if(statusMessageValue != null) {
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(statusMessageValue));
+ }
+ moaError = statusMessager.mapInternalErrorToExternalError(ex.getErrorId());
+
+ } else {
+ statusCode.setValue(StatusCode.RESPONDER_URI);
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
+ moaError = statusMessager.getResponseErrorCode(e);
+ }
+
+
+ if (StringUtils.isNotEmpty(moaError)) {
+ StatusCode moaStatusCode = SAML2Utils.createSAMLObject(StatusCode.class);
+ moaStatusCode.setValue(moaError);
+ statusCode.setStatusCode(moaStatusCode);
+ }
+
+ status.setStatusCode(statusCode);
+ if(statusMessage.getMessage() != null) {
+ status.setStatusMessage(statusMessage);
+ }
+ samlResponse.setStatus(status);
+ String remoteSessionID = SAML2Utils.getSecureIdentifier();
+ samlResponse.setID(remoteSessionID);
+
+ samlResponse.setIssueInstant(new DateTime());
+ Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
+ nissuer.setValue(pvpBasicConfiguration.getIDPEntityId(pvpRequest.getAuthURL()));
+ nissuer.setFormat(NameID.ENTITY);
+ samlResponse.setIssuer(nissuer);
+
+ IEncoder encoder = null;
+
+ if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ encoder = applicationContext.getBean("PVPRedirectBinding", RedirectBinding.class);
+
+ } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
+ encoder = applicationContext.getBean("PVPPOSTBinding", PostBinding.class);
+
+ } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) {
+ encoder = applicationContext.getBean("PVPSOAPBinding", SoapBinding.class);
+ }
+
+ if(encoder == null) {
+ // default to redirect binding
+ encoder = new RedirectBinding();
+ }
+
+ String relayState = null;
+ if (pvpRequest.getRequest() != null)
+ relayState = pvpRequest.getRequest().getRelayState();
+
+ X509Credential signCred = pvpIDPCredentials.getIDPAssertionSigningCredential();
+
+ encoder.encodeRespone(request, response, samlResponse, pvpRequest.getConsumerURL(),
+ relayState, signCred, protocolRequest);
+ return true;
+ }
+
+ public boolean validate(HttpServletRequest request,
+ HttpServletResponse response, IRequest pending) {
+
+ return true;
+ }
+
+ protected void pvpMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ //create pendingRequest object
+ PVPSProfilePendingRequest pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class);
+ pendingReq.initialize(req, authConfig);
+ pendingReq.setModule(getName());
+
+ revisionsLogger.logEvent(
+ pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(),
+ EventConstants.TRANSACTION_IP,
+ req.getRemoteAddr());
+
+ MetadataAction metadataAction = applicationContext.getBean(MetadataAction.class);
+ metadataAction.processRequest(pendingReq,
+ req, resp, null);
+
+ }
+
+ protected void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ PVPSProfilePendingRequest pendingReq = null;
+
+ try {
+ //create pendingRequest object
+ pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class);
+ pendingReq.initialize(req, authConfig);
+ pendingReq.setModule(getName());
+
+ revisionsLogger.logEvent(EventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(
+ pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(),
+ EventConstants.TRANSACTION_IP,
+ req.getRemoteAddr());
+
+ //get POST-Binding decoder implementation
+ InboundMessage msg = (InboundMessage) new PostBinding().decode(
+ req, resp, metadataProvider, false,
+ new EAAFURICompare(pvpBasicConfiguration.getIDPSSOPostService(pendingReq.getAuthURL())));
+ pendingReq.setRequest(msg);
+
+ //preProcess Message
+ preProcess(req, resp, pendingReq);
+
+ } catch (SecurityPolicyException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+
+ } catch (SecurityException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()});
+
+ } catch (EAAFException e) {
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw e;
+
+ } catch (Throwable e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new EAAFException("pvp2.24", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+ protected void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ PVPSProfilePendingRequest pendingReq = null;
+ try {
+ //create pendingRequest object
+ pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class);
+ pendingReq.initialize(req, authConfig);
+ pendingReq.setModule(getName());
+
+ revisionsLogger.logEvent(EventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(
+ pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(),
+ EventConstants.TRANSACTION_IP,
+ req.getRemoteAddr());
+
+ //get POST-Binding decoder implementation
+ InboundMessage msg = (InboundMessage) new RedirectBinding().decode(
+ req, resp, metadataProvider, false,
+ new EAAFURICompare(pvpBasicConfiguration.getIDPSSORedirectService(pendingReq.getAuthURL())));
+ pendingReq.setRequest(msg);
+
+ //preProcess Message
+ preProcess(req, resp, pendingReq);
+
+ } catch (SecurityPolicyException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+
+ } catch (SecurityException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()});
+
+ } catch (EAAFException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.info("Receive INVALID protocol request: " + samlRequest);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw e;
+
+ } catch (Throwable e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new EAAFException("pvp2.24", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+
+
+ /**
+ *
+ *
+ * @param request
+ * @param response
+ * @param msg
+ * @return true if preprocess can handle this request type, otherwise false
+ * @throws Throwable
+ */
+ abstract protected boolean childPreProcess(HttpServletRequest request,
+ HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable;
+
+ protected void preProcess(HttpServletRequest request,
+ HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable {
+
+ InboundMessage msg = pendingReq.getRequest();
+
+ if (StringUtils.isEmpty(msg.getEntityID())) {
+ throw new InvalidProtocolRequestException("pvp2.20", new Object[] {});
+
+ }
+
+ if(!msg.isVerified()) {
+ samlVerificationEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ msg.setVerified(true);
+
+ }
+
+ revisionsLogger.logEvent(pendingReq, IRevisionLogger.AUTHPROTOCOL_TYPE, getAuthProtocolIdentifier());
+
+ if (msg instanceof PVPSProfileRequest &&
+ ((PVPSProfileRequest)msg).getSamlRequest() instanceof AuthnRequest)
+ preProcessAuthRequest(request, response, pendingReq);
+
+ else if (childPreProcess(request, response, pendingReq))
+ log.debug("Find protocol handler in child implementation");
+
+ else {
+ log.error("Receive unsupported PVP21 message of type: " + ((PVPSProfileRequest)msg).getSamlRequest().getClass().getName());
+ throw new InvalidPVPRequestException("pvp2.09",
+ new Object[] {((PVPSProfileRequest)msg).getSamlRequest().getClass().getName()});
+ }
+
+
+
+ //switch to session authentication
+ protAuthService.performAuthentication(request, response, pendingReq);
+ }
+
+
+ /**
+ * PreProcess Authn request
+ * @param request
+ * @param response
+ * @param pendingReq
+ * @throws Throwable
+ */
+ private void preProcessAuthRequest(HttpServletRequest request,
+ HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable {
+
+ PVPSProfileRequest moaRequest = ((PVPSProfileRequest)pendingReq.getRequest());
+ SignableXMLObject samlReq = moaRequest.getSamlRequest();
+
+ if(!(samlReq instanceof AuthnRequest)) {
+ throw new InvalidPVPRequestException("Unsupported request", new Object[] {});
+ }
+
+ EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider);
+ if(metadata == null) {
+ throw new NoMetadataInformationException();
+ }
+ SPSSODescriptor spSSODescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+
+ AuthnRequest authnRequest = (AuthnRequest)samlReq;
+
+ if (authnRequest.getIssueInstant() == null) {
+ log.warn("Unsupported request: No IssueInstant Attribute found.");
+ throw new AuthnRequestValidatorException("pvp2.22",
+ new Object[] {"Unsupported request: No IssueInstant Attribute found"},
+ pendingReq);
+
+ }
+
+ if (authnRequest.getIssueInstant().minusMinutes(EAAFConstants.ALLOWED_TIME_JITTER).isAfterNow()) {
+ log.warn("Unsupported request: No IssueInstant DateTime is not valid anymore.");
+ throw new AuthnRequestValidatorException("pvp2.22",
+ new Object[] {"Unsupported request: No IssueInstant DateTime is not valid anymore."},
+ pendingReq);
+
+ }
+
+ //parse AssertionConsumerService
+ AssertionConsumerService consumerService = null;
+ if (StringUtils.isNotEmpty(authnRequest.getAssertionConsumerServiceURL()) &&
+ StringUtils.isNotEmpty(authnRequest.getProtocolBinding())) {
+ //use AssertionConsumerServiceURL from request
+
+ //check requested AssertionConsumingService URL against metadata
+ List<AssertionConsumerService> metadataAssertionServiceList = spSSODescriptor.getAssertionConsumerServices();
+ for (AssertionConsumerService service : metadataAssertionServiceList) {
+ if (authnRequest.getProtocolBinding().equals(service.getBinding())
+ && authnRequest.getAssertionConsumerServiceURL().equals(service.getLocation())) {
+ consumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class);
+ consumerService.setBinding(authnRequest.getProtocolBinding());
+ consumerService.setLocation(authnRequest.getAssertionConsumerServiceURL());
+ log.debug("Requested AssertionConsumerServiceURL is valid.");
+ }
+ }
+
+ if (consumerService == null) {
+ throw new InvalidAssertionConsumerServiceException(authnRequest.getAssertionConsumerServiceURL());
+
+ }
+
+
+ } else {
+ //use AssertionConsumerServiceIndex and select consumerService from metadata
+ Integer aIdx = authnRequest.getAssertionConsumerServiceIndex();
+ int assertionidx = 0;
+
+ if(aIdx != null) {
+ assertionidx = aIdx.intValue();
+
+ } else {
+ assertionidx = SAML2Utils.getDefaultAssertionConsumerServiceIndex(spSSODescriptor);
+
+ }
+ consumerService = spSSODescriptor.getAssertionConsumerServices().get(assertionidx);
+
+ if (consumerService == null) {
+ throw new InvalidAssertionConsumerServiceException(aIdx);
+
+ }
+ }
+
+
+ //validate AuthnRequest
+ AuthnRequest authReq = (AuthnRequest) samlReq;
+ String oaURL = moaRequest.getEntityMetadata(metadataProvider).getEntityID();
+ log.info("Dispatch PVP2 AuthnRequest: OAURL=" + oaURL + " Binding=" + consumerService.getBinding());
+
+ pendingReq.setSPEntityId(StringEscapeUtils.escapeHtml(oaURL));
+ pendingReq.setOnlineApplicationConfiguration(authConfig.getServiceProviderConfiguration(pendingReq.getSPEntityId()));
+ pendingReq.setBinding(consumerService.getBinding());
+ pendingReq.setRequest(moaRequest);
+ pendingReq.setConsumerURL(consumerService.getLocation());
+
+ //parse AuthRequest
+ pendingReq.setPassiv(authReq.isPassive());
+ pendingReq.setForce(authReq.isForceAuthn());
+
+ //AuthnRequest needs authentication
+ pendingReq.setNeedAuthentication(true);
+
+ //set protocol action, which should be executed after authentication
+ pendingReq.setAction(AuthenticationAction.class.getName());
+
+ // do post-processing if required
+ log.trace("Starting extended AuthnRequest validation and processing ... ");
+ if (authRequestPostProcessors != null) {
+ for (final IAuthnRequestPostProcessor processor : authRequestPostProcessors) {
+ log.trace("Post-process AuthnRequest with module: {}", processor.getClass().getSimpleName());
+ processor.process(request, pendingReq, authReq, spSSODescriptor);
+
+ }
+ }
+
+ log.debug("Extended AuthnRequest validation and processing finished");
+
+ //write revisionslog entry
+ revisionsLogger.logEvent(pendingReq, PVPEventConstants.AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST, authReq.getID());
+
+ }
+
+ @PostConstruct
+ private void verifyInitialization() {
+ if (pvpIDPCredentials == null) {
+ log.error("No SAML2 credentialProvider injected!");
+ throw new RuntimeException("No SAML2 credentialProvider injected!");
+
+ }
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java
index cbbed659..f9d7767f 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.impl;
import javax.annotation.PostConstruct;
@@ -31,14 +24,12 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime;
-import org.opensaml.common.xml.SAMLConstants;
-import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.AuthnRequest;
-import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.metadata.AssertionConsumerService;
-import org.opensaml.saml2.metadata.EntityDescriptor;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
-import org.opensaml.xml.security.SecurityException;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,137 +40,139 @@ import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.idp.IAction;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
+import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.impl.data.SLOInformationImpl;
-import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.data.SloInformationImpl;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration;
import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider;
import at.gv.egiz.eaaf.modules.pvp2.exception.BindingNotSupportedException;
import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException;
import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.AuthResponseBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.PVP2AssertionBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.Pvp2AssertionBuilder;
import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
-import at.gv.egiz.eaaf.modules.pvp2.impl.message.PVPSProfileRequest;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
@Service("PVPAuthenticationRequestAction")
public class AuthenticationAction implements IAction {
- private static final Logger log = LoggerFactory.getLogger(AuthenticationAction.class);
-
- private static final String CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION = "protocols.pvp2.assertion.encryption.active";
-
- @Autowired(required=true) private IPVPMetadataProvider metadataProvider;
- @Autowired(required=true) ApplicationContext springContext;
- @Autowired(required=true) IConfiguration authConfig;
- @Autowired(required=true) PVP2AssertionBuilder assertionBuilder;
- @Autowired(required=true) IPVP2BasicConfiguration pvpBasicConfiguration;
- @Autowired(required=true) IRevisionLogger revisionsLogger;
-
- private AbstractCredentialProvider pvpIDPCredentials;
-
- /**
- * Sets a specific credential provider for PVP S-Profile IDP component.
- * @param pvpIDPCredentials credential provider
- */
- public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) {
- this.pvpIDPCredentials = pvpIDPCredentials;
-
- }
-
- @Override
- public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq,
- HttpServletResponse httpResp, IAuthData authData) throws ResponderErrorException {
- final PVPSProfilePendingRequest pvpRequest = (PVPSProfilePendingRequest) req;
- try {
- //get basic information
- final PVPSProfileRequest moaRequest = (PVPSProfileRequest) pvpRequest.getRequest();
- final AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest();
- final EntityDescriptor peerEntity = moaRequest.getEntityMetadata(metadataProvider);
-
- final AssertionConsumerService consumerService =
- SAML2Utils.createSAMLObject(AssertionConsumerService.class);
- consumerService.setBinding(pvpRequest.getBinding());
- consumerService.setLocation(pvpRequest.getConsumerURL());
-
- final DateTime date = new DateTime();
- final SLOInformationImpl sloInformation = new SLOInformationImpl();
- final String issuerEntityID = pvpBasicConfiguration.getIDPEntityId(pvpRequest.getAuthURL());
-
- //build Assertion
- final Assertion assertion = assertionBuilder.buildAssertion(issuerEntityID, pvpRequest, authnRequest, authData,
- peerEntity, date, consumerService, sloInformation);
-
- final Response authResponse = AuthResponseBuilder.buildResponse(
- metadataProvider, issuerEntityID, authnRequest,
- date, assertion, authConfig.getBasicConfigurationBoolean(
- CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION, true));
-
- IEncoder binding = null;
-
- if (consumerService.getBinding().equals(
- SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
- binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class);
-
- } else if (consumerService.getBinding().equals(
- SAMLConstants.SAML2_POST_BINDING_URI)) {
- binding = springContext.getBean("PVPPOSTBinding", PostBinding.class);
-
- }
-
- if (binding == null) {
- throw new BindingNotSupportedException(consumerService.getBinding());
- }
-
- binding.encodeRespone(httpReq, httpResp, authResponse,
- consumerService.getLocation(), moaRequest.getRelayState(),
- pvpIDPCredentials.getIDPAssertionSigningCredential(), req);
-
- revisionsLogger.logEvent(req, 3105, authResponse.getID());
-
- //set protocol type
- sloInformation.setProtocolType(req.requestedModule());
- sloInformation.setSpEntityID(req.getServiceProviderConfiguration().getUniqueIdentifier());
- return sloInformation;
-
- } catch (MessageEncodingException | SecurityException e) {
- log.warn("Message Encoding exception", e);
- throw new ResponderErrorException("pvp2.01", null, e);
-
- } catch (final EAAFException e) {
- log.info("Response generation error: Msg: ", e.getMessage());
- throw new ResponderErrorException(e.getErrorId(), e.getParams(), e);
-
- } catch (final Exception e) {
- log.warn("Response generation error", e);
- throw new ResponderErrorException("pvp2.01", null, e);
-
- }
-
- }
-
- @Override
- public boolean needAuthentication(IRequest req, HttpServletRequest httpReq,
- HttpServletResponse httpResp) {
- return true;
- }
-
- @Override
- public String getDefaultActionName() {
- return "PVPAuthenticationRequestAction";
-
- }
-
- @PostConstruct
- private void verifyInitialization() {
- if (pvpIDPCredentials == null) {
- log.error("No SAML2 credentialProvider injected!");
- throw new RuntimeException("No SAML2 credentialProvider injected!");
-
- }
- }
+ private static final Logger log = LoggerFactory.getLogger(AuthenticationAction.class);
+
+ @Autowired(required = true)
+ private IPvp2MetadataProvider metadataProvider;
+ @Autowired(required = true)
+ ApplicationContext springContext;
+ @Autowired(required = true)
+ IConfiguration authConfig;
+ @Autowired(required = true)
+ Pvp2AssertionBuilder assertionBuilder;
+ @Autowired(required = true)
+ IPvp2BasicConfiguration pvpBasicConfiguration;
+ @Autowired(required = true)
+ IRevisionLogger revisionsLogger;
+
+ private IPvp2CredentialProvider pvpIdpCredentials;
+
+ /**
+ * Sets a specific credential provider for PVP S-Profile IDP component.
+ *
+ * @param pvpIdpCredentials credential provider
+ */
+ public void setPvpIdpCredentials(final IPvp2CredentialProvider pvpIdpCredentials) {
+ this.pvpIdpCredentials = pvpIdpCredentials;
+
+ }
+
+ @Override
+ public SloInformationInterface processRequest(final IRequest req,
+ final HttpServletRequest httpReq, final HttpServletResponse httpResp,
+ final IAuthData authData) throws ResponderErrorException {
+ final PvpSProfilePendingRequest pvpRequest = (PvpSProfilePendingRequest) req;
+ try {
+ // get basic information
+ final PvpSProfileRequest moaRequest = (PvpSProfileRequest) pvpRequest.getRequest();
+ final AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest();
+ final EntityDescriptor peerEntity = moaRequest.getEntityMetadata(metadataProvider);
+
+ final AssertionConsumerService consumerService =
+ Saml2Utils.createSamlObject(AssertionConsumerService.class);
+ consumerService.setBinding(pvpRequest.getBinding());
+ consumerService.setLocation(pvpRequest.getConsumerUrl());
+
+ final DateTime date = new DateTime();
+ final SloInformationImpl sloInformation = new SloInformationImpl();
+ final String issuerEntityID = pvpBasicConfiguration.getIdpEntityId(pvpRequest.getAuthUrl());
+
+ // build Assertion
+ final Assertion assertion = assertionBuilder.buildAssertion(issuerEntityID, pvpRequest,
+ authnRequest, authData, peerEntity, date, consumerService, sloInformation);
+
+ final Response authResponse = AuthResponseBuilder.buildResponse(metadataProvider,
+ issuerEntityID, authnRequest, date, assertion,
+ authConfig);
+
+ IEncoder binding = null;
+
+ if (consumerService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ binding = springContext.getBean("PvpRedirectBinding", RedirectBinding.class);
+
+ } else if (consumerService.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
+ binding = springContext.getBean("PvpPostBinding", PostBinding.class);
+
+ }
+
+ if (binding == null) {
+ throw new BindingNotSupportedException(consumerService.getBinding());
+ }
+
+ binding.encodeResponse(httpReq, httpResp, authResponse, consumerService.getLocation(),
+ moaRequest.getRelayState(), pvpIdpCredentials.getMessageSigningCredential(), req);
+
+ revisionsLogger.logEvent(req, 3105, authResponse.getID());
+
+ // set protocol type
+ sloInformation.setProtocolType(req.requestedModule());
+ sloInformation.setSpEntityID(req.getServiceProviderConfiguration().getUniqueIdentifier());
+ return sloInformation;
+
+ } catch (final SecurityException e) {
+ log.warn("Message Encoding exception", e);
+ throw new ResponderErrorException("pvp2.01", null, e);
+
+ } catch (final EaafException e) {
+ log.info("Response generation error: Msg: ", e.getMessage());
+ throw new ResponderErrorException(e.getErrorId(), e.getParams(), e);
+
+ } catch (final Exception e) {
+ log.warn("Response generation error", e);
+ throw new ResponderErrorException("pvp2.01", null, e);
+
+ }
+
+ }
+
+ @Override
+ public boolean needAuthentication(final IRequest req, final HttpServletRequest httpReq,
+ final HttpServletResponse httpResp) {
+ return true;
+ }
+
+ @Override
+ public String getDefaultActionName() {
+ return "PVPAuthenticationRequestAction";
+
+ }
+
+ @PostConstruct
+ private void verifyInitialization() {
+ if (pvpIdpCredentials == null) {
+ log.error("No SAML2 credentialProvider injected!");
+ throw new RuntimeException("No SAML2 credentialProvider injected!");
+
+ }
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java
index 6b957522..0b344ba3 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/MetadataAction.java
@@ -1,123 +1,120 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.impl;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IAction;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+import at.gv.egiz.eaaf.modules.pvp2.PvpEventConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.api.idp.IAction;
-import at.gv.egiz.eaaf.core.api.idp.IAuthData;
-import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
-import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
-import at.gv.egiz.eaaf.modules.pvp2.PVPEventConstants;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataBuilderConfiguration;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataConfigurationFactory;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2MetadataException;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPMetadataBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
-
@Service("pvpMetadataService")
public class MetadataAction implements IAction {
- private static final Logger log = LoggerFactory.getLogger(MetadataAction.class);
-
- @Autowired private IRevisionLogger revisionsLogger;
- @Autowired private PVPMetadataBuilder metadatabuilder;
- @Autowired private IPVPMetadataConfigurationFactory configFactory;
-
- private AbstractCredentialProvider pvpIDPCredentials;
-
- /**
- * Sets a specific credential provider for PVP S-Profile IDP component.
- * @param pvpIDPCredentials credential provider
- */
- public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) {
- this.pvpIDPCredentials = pvpIDPCredentials;
-
- }
-
- public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq,
- HttpServletResponse httpResp, IAuthData authData) throws PVP2MetadataException {
- try {
- revisionsLogger.logEvent(req, PVPEventConstants.AUTHPROTOCOL_PVP_METADATA);
-
- //build metadata
- IPVPMetadataBuilderConfiguration metadataConfig =
- configFactory.generateMetadataBuilderConfiguration(
- req.getAuthURLWithOutSlash(),
- pvpIDPCredentials);
-
- ;
-
- String metadataXML = metadatabuilder.buildPVPMetadata(metadataConfig);
- log.debug("METADATA: " + metadataXML);
-
- byte[] content = metadataXML.getBytes("UTF-8");
- httpResp.setStatus(HttpServletResponse.SC_OK);
- httpResp.setContentLength(content.length);
- httpResp.setContentType(MediaType.APPLICATION_XML_VALUE);
- httpResp.getOutputStream().write(content);
- return null;
-
- } catch (Exception e) {
- log.error("Failed to generate metadata", e);
- throw new PVP2MetadataException("pvp2.27", null);
- }
- }
-
- public boolean needAuthentication(IRequest req, HttpServletRequest httpReq,
- HttpServletResponse httpResp) {
- return false;
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
- */
- @Override
- public String getDefaultActionName() {
- return "IDP - PVP Metadata action";
- }
-
- @PostConstruct
- private void verifyInitialization() {
- if (pvpIDPCredentials == null) {
- log.error("No SAML2 credentialProvider injected!");
- throw new RuntimeException("No SAML2 credentialProvider injected!");
-
- }
- }
-
+ private static final Logger log = LoggerFactory.getLogger(MetadataAction.class);
+
+ @Autowired
+ private IRevisionLogger revisionsLogger;
+ @Autowired
+ private PvpMetadataBuilder metadatabuilder;
+ @Autowired
+ private IPvpMetadataConfigurationFactory configFactory;
+
+ private IPvp2CredentialProvider pvpIdpCredentials;
+
+ /**
+ * Sets a specific credential provider for PVP S-Profile IDP component.
+ *
+ * @param pvpIdpCredentials credential provider
+ */
+ public void setPvpIdpCredentials(final IPvp2CredentialProvider pvpIdpCredentials) {
+ this.pvpIdpCredentials = pvpIdpCredentials;
+
+ }
+
+ @Override
+ public SloInformationInterface processRequest(final IRequest req,
+ final HttpServletRequest httpReq, final HttpServletResponse httpResp,
+ final IAuthData authData) throws Pvp2MetadataException {
+ try {
+ revisionsLogger.logEvent(req, PvpEventConstants.AUTHPROTOCOL_PVP_METADATA);
+
+ // build metadata
+ final IPvpMetadataBuilderConfiguration metadataConfig = configFactory
+ .generateMetadataBuilderConfiguration(req.getAuthUrlWithOutSlash(), pvpIdpCredentials);
+
+ final String metadataXml = metadatabuilder.buildPvpMetadata(metadataConfig);
+ log.trace("METADATA: " + metadataXml);
+
+ final byte[] content = metadataXml.getBytes("UTF-8");
+ httpResp.setStatus(HttpServletResponse.SC_OK);
+ httpResp.setContentLength(content.length);
+ httpResp.setContentType(MediaType.APPLICATION_XML_VALUE);
+ httpResp.getOutputStream().write(content);
+ return null;
+
+ } catch (final Exception e) {
+ log.error("Failed to generate metadata", e);
+ throw new Pvp2MetadataException("pvp2.27", null);
+ }
+ }
+
+ @Override
+ public boolean needAuthentication(final IRequest req, final HttpServletRequest httpReq,
+ final HttpServletResponse httpResp) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ @Override
+ public String getDefaultActionName() {
+ return "IDP - PVP Metadata action";
+ }
+
+ @PostConstruct
+ private void verifyInitialization() {
+ if (pvpIdpCredentials == null) {
+ log.error("No SAML2 credentialProvider injected!");
+ throw new RuntimeException("No SAML2 credentialProvider injected!");
+
+ }
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java
deleted file mode 100644
index 7f086ff6..00000000
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PVPSProfilePendingRequest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.modules.pvp2.idp.impl;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.context.annotation.Scope;
-import org.springframework.stereotype.Component;
-
-import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
-import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage;
-
-@Component("PVPSProfilePendingRequest")
-@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
-public class PVPSProfilePendingRequest extends RequestImpl {
- private static final long serialVersionUID = 4889919265919638188L;
-
- InboundMessage request;
- String binding;
- String consumerURL;
-
- public InboundMessage getRequest() {
- return request;
- }
-
- public void setRequest(InboundMessage request) {
- this.request = request;
- }
-
- public String getBinding() {
- return binding;
- }
-
- public void setBinding(String binding) {
- this.binding = binding;
- }
-
- public String getConsumerURL() {
- return consumerURL;
- }
-
- public void setConsumerURL(String consumerURL) {
- this.consumerURL = consumerURL;
-
- }
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java
new file mode 100644
index 00000000..26e04881
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/PvpSProfilePendingRequest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.idp.impl;
+
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Component("PVPSProfilePendingRequest")
+@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
+public class PvpSProfilePendingRequest extends RequestImpl {
+ private static final long serialVersionUID = 4889919265919638188L;
+
+ InboundMessage request;
+ String binding;
+ String consumerUrl;
+
+ public InboundMessage getRequest() {
+ return request;
+ }
+
+ public void setRequest(final InboundMessage request) {
+ this.request = request;
+ }
+
+ public String getBinding() {
+ return binding;
+ }
+
+ public void setBinding(final String binding) {
+ this.binding = binding;
+ }
+
+ public String getConsumerUrl() {
+ return consumerUrl;
+ }
+
+ public void setConsumerUrl(final String consumerUrl) {
+ this.consumerUrl = consumerUrl;
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java
index 07423c19..482a2a09 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java
@@ -1,153 +1,215 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder;
import java.util.ArrayList;
import java.util.List;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+
import org.joda.time.DateTime;
-import org.opensaml.Configuration;
-import org.opensaml.common.xml.SAMLConstants;
-import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.EncryptedAssertion;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.NameID;
-import org.opensaml.saml2.core.RequestAbstractType;
-import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.encryption.Encrypter;
-import org.opensaml.saml2.encryption.Encrypter.KeyPlacement;
-import org.opensaml.saml2.metadata.SPSSODescriptor;
-import org.opensaml.saml2.metadata.provider.MetadataProvider;
-import org.opensaml.security.MetadataCredentialResolver;
-import org.opensaml.security.MetadataCriteria;
-import org.opensaml.xml.encryption.EncryptionException;
-import org.opensaml.xml.encryption.EncryptionParameters;
-import org.opensaml.xml.encryption.KeyEncryptionParameters;
-import org.opensaml.xml.security.CriteriaSet;
-import org.opensaml.xml.security.SecurityException;
-import org.opensaml.xml.security.credential.UsageType;
-import org.opensaml.xml.security.criteria.EntityIDCriteria;
-import org.opensaml.xml.security.criteria.UsageCriteria;
-import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory;
-import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.criterion.EntityRoleCriterion;
+import org.opensaml.saml.criterion.ProtocolCriterion;
+import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.EncryptedAssertion;
+import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.core.RequestAbstractType;
+import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.encryption.Encrypter;
+import org.opensaml.saml.saml2.encryption.Encrypter.KeyPlacement;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml.security.impl.MetadataCredentialResolver;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.criteria.UsageCriterion;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.xmlsec.SecurityConfigurationSupport;
+import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters;
+import org.opensaml.xmlsec.encryption.support.EncryptionException;
+import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters;
+import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
+import org.opensaml.xmlsec.keyinfo.KeyInfoGeneratorFactory;
+import org.opensaml.xmlsec.keyinfo.impl.BasicProviderKeyInfoCredentialResolver;
+import org.opensaml.xmlsec.keyinfo.impl.KeyInfoProvider;
+import org.opensaml.xmlsec.keyinfo.impl.provider.DSAKeyValueProvider;
+import org.opensaml.xmlsec.keyinfo.impl.provider.InlineX509DataProvider;
+import org.opensaml.xmlsec.keyinfo.impl.provider.RSAKeyValueProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
-import at.gv.egiz.eaaf.modules.pvp2.PVPConstants;
-import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
/**
+ * Authentication response builder.
+ *
* @author tlenz
*
*/
public class AuthResponseBuilder {
- private static final Logger log = LoggerFactory.getLogger(AuthResponseBuilder.class);
-
- public static Response buildResponse(MetadataProvider metadataProvider, String issuerEntityID, RequestAbstractType req, DateTime date, Assertion assertion, boolean enableEncryption) throws InvalidAssertionEncryptionException {
- Response authResponse = SAML2Utils.createSAMLObject(Response.class);
-
- Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
-
- nissuer.setValue(issuerEntityID);
- nissuer.setFormat(NameID.ENTITY);
- authResponse.setIssuer(nissuer);
- authResponse.setInResponseTo(req.getID());
-
- //set responseID
- String remoteSessionID = SAML2Utils.getSecureIdentifier();
- authResponse.setID(remoteSessionID);
-
-
- //SAML2 response required IssueInstant
- authResponse.setIssueInstant(date);
-
- authResponse.setStatus(SAML2Utils.getSuccessStatus());
-
- //check, if metadata includes an encryption key
- MetadataCredentialResolver mdCredResolver =
- new MetadataCredentialResolver(metadataProvider);
-
- CriteriaSet criteriaSet = new CriteriaSet();
- criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) );
- criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) );
- criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) );
-
- X509Credential encryptionCredentials = null;
- try {
- encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet);
-
- } catch (SecurityException e2) {
- log.warn("Can not extract the Assertion Encryption-Key from metadata", e2);
- throw new InvalidAssertionEncryptionException();
-
- }
-
- if (encryptionCredentials != null && enableEncryption) {
- //encrypt SAML2 assertion
-
- try {
-
- EncryptionParameters dataEncParams = new EncryptionParameters();
- dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE);
-
- List<KeyEncryptionParameters> keyEncParamList = new ArrayList<KeyEncryptionParameters>();
- KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
-
- keyEncParam.setEncryptionCredential(encryptionCredentials);
- keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE);
- KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration()
- .getKeyInfoGeneratorManager().getDefaultManager()
- .getFactory(encryptionCredentials);
- keyEncParam.setKeyInfoGenerator(kigf.newInstance());
- keyEncParamList.add(keyEncParam);
-
- Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
- //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE);
- samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
-
- EncryptedAssertion encryptAssertion = null;
-
- encryptAssertion = samlEncrypter.encrypt(assertion);
-
- authResponse.getEncryptedAssertions().add(encryptAssertion);
-
- } catch (EncryptionException e1) {
- log.warn("Can not encrypt the PVP2 assertion", e1);
- throw new InvalidAssertionEncryptionException();
-
- }
-
- } else {
- authResponse.getAssertions().add(assertion);
-
- }
-
- return authResponse;
- }
+ private static final Logger log = LoggerFactory.getLogger(AuthResponseBuilder.class);
+
+ /**
+ * Build PVP2 S-Profile authentication response.
+ *
+ * @param metadataProvider Service-Provider metadata
+ * @param issuerEntityID IDP entityId
+ * @param req current pending request
+ * @param date Timestamp
+ * @param assertion PVP2 S-Profil Assertion
+ * @param authConfig {@link IConfiguration}
+ * @return PVP2 S-Profile authentication response
+ * @throws InvalidAssertionEncryptionException In case of an error
+ */
+ public static Response buildResponse(final IPvp2MetadataProvider metadataProvider,
+ final String issuerEntityID, final RequestAbstractType req, final DateTime date,
+ final Assertion assertion, IConfiguration authConfig)
+ throws InvalidAssertionEncryptionException {
+ final Response authResponse = Saml2Utils.createSamlObject(Response.class);
+
+ final Issuer nissuer = Saml2Utils.createSamlObject(Issuer.class);
+
+ nissuer.setValue(issuerEntityID);
+ nissuer.setFormat(NameIDType.ENTITY);
+ authResponse.setIssuer(nissuer);
+ authResponse.setInResponseTo(req.getID());
+
+ // set responseID
+ final String remoteSessionID = Saml2Utils.getSecureIdentifier();
+ authResponse.setID(remoteSessionID);
+
+ // SAML2 response required IssueInstant
+ authResponse.setIssueInstant(date);
+
+ authResponse.setStatus(Saml2Utils.getSuccessStatus());
+
+ // check, if metadata includes an encryption key
+ final X509Credential encryptionCredentials = resolveEncryptionCredential(req, metadataProvider);
+
+ if (encryptionCredentials != null
+ && authConfig.getBasicConfigurationBoolean(
+ PvpConstants.CONFIG_PROPERTY_PVP2_ENABLE_ENCRYPTION, true)) {
+ authResponse.getEncryptedAssertions().add(
+ doEncryption(assertion, encryptionCredentials, authConfig));
+
+ } else {
+ authResponse.getAssertions().add(assertion);
+
+ }
+
+ return authResponse;
+ }
+
+ private static EncryptedAssertion doEncryption(Assertion assertion,
+ X509Credential encryptionCredentials, IConfiguration authConfig)
+ throws InvalidAssertionEncryptionException {
+ try {
+ final String keyEncAlg = Saml2Utils.getKeyOperationAlgorithmFromCredential(
+ encryptionCredentials,
+ authConfig.getBasicConfiguration(
+ PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_RSA_ALG,
+ PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_RSA),
+ authConfig.getBasicConfiguration(
+ PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_EC_ALG,
+ PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_EC));
+
+ final DataEncryptionParameters dataEncParams = new DataEncryptionParameters();
+ dataEncParams.setAlgorithm(authConfig.getBasicConfiguration(
+ PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_DATA, PvpConstants.DEFAULT_SYM_ENCRYPTION_METHODE));
+
+ final List<KeyEncryptionParameters> keyEncParamList = new ArrayList<>();
+ final KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
+ keyEncParam.setEncryptionCredential(encryptionCredentials);
+ keyEncParam.setAlgorithm(keyEncAlg);
+
+ final KeyInfoGeneratorFactory kigf =
+ SecurityConfigurationSupport.getGlobalEncryptionConfiguration()
+ .getKeyTransportKeyInfoGeneratorManager().getDefaultManager().getFactory(encryptionCredentials);
+ keyEncParam.setKeyInfoGenerator(kigf.newInstance());
+ keyEncParamList.add(keyEncParam);
+
+ final Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
+ samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
+
+ final Element assertionElement = XMLObjectProviderRegistrySupport.getMarshallerFactory()
+ .getMarshaller(assertion).marshall(assertion);
+ assertionElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xs", "http://www.w3.org/2001/XMLSchema");
+
+ return samlEncrypter.encrypt((Assertion)
+ XMLObjectSupport.getUnmarshaller(assertionElement).unmarshall(assertionElement));
+
+ } catch (final EncryptionException | SamlSigningException | MarshallingException | UnmarshallingException e1) {
+ log.warn("Can not encrypt the PVP2 assertion", e1);
+ throw new InvalidAssertionEncryptionException();
+
+ }
+
+ }
+
+ private static X509Credential resolveEncryptionCredential(RequestAbstractType req,
+ IPvp2MetadataProvider metadataProvider) throws InvalidAssertionEncryptionException {
+ try {
+ final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>();
+ keyInfoProvider.add(new DSAKeyValueProvider());
+ keyInfoProvider.add(new RSAKeyValueProvider());
+ keyInfoProvider.add(new InlineX509DataProvider());
+ final KeyInfoCredentialResolver keyInfoCredentialResolver = new BasicProviderKeyInfoCredentialResolver(
+ keyInfoProvider);
+
+ final PredicateRoleDescriptorResolver roleDescriptorResolver = new PredicateRoleDescriptorResolver(
+ metadataProvider);
+ roleDescriptorResolver.setRequireValidMetadata(true);
+ roleDescriptorResolver.initialize();
+
+ final MetadataCredentialResolver mdCredResolver = new MetadataCredentialResolver();
+ mdCredResolver.setRoleDescriptorResolver(roleDescriptorResolver);
+ mdCredResolver.setKeyInfoCredentialResolver(keyInfoCredentialResolver);
+ mdCredResolver.initialize();
+
+ final CriteriaSet criteriaSet = new CriteriaSet();
+ criteriaSet.add(new EntityIdCriterion(req.getIssuer().getValue()));
+ criteriaSet.add(new ProtocolCriterion(SAMLConstants.SAML20P_NS));
+ criteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
+ criteriaSet.add(new UsageCriterion(UsageType.ENCRYPTION));
+
+ return (X509Credential) mdCredResolver.resolveSingle(criteriaSet);
+
+ } catch (final SecurityException | ComponentInitializationException | ResolverException e2) {
+ log.warn("Can not extract the Assertion Encryption-Key from metadata", e2);
+ throw new InvalidAssertionEncryptionException();
+
+ }
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java
deleted file mode 100644
index 2ccc2c9e..00000000
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.joda.time.DateTime;
-import org.opensaml.common.xml.SAMLConstants;
-import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.Attribute;
-import org.opensaml.saml2.core.AttributeQuery;
-import org.opensaml.saml2.core.AttributeStatement;
-import org.opensaml.saml2.core.Audience;
-import org.opensaml.saml2.core.AudienceRestriction;
-import org.opensaml.saml2.core.AuthnContext;
-import org.opensaml.saml2.core.AuthnContextClassRef;
-import org.opensaml.saml2.core.AuthnRequest;
-import org.opensaml.saml2.core.AuthnStatement;
-import org.opensaml.saml2.core.Conditions;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.NameID;
-import org.opensaml.saml2.core.RequestedAuthnContext;
-import org.opensaml.saml2.core.Subject;
-import org.opensaml.saml2.core.SubjectConfirmation;
-import org.opensaml.saml2.core.SubjectConfirmationData;
-import org.opensaml.saml2.core.impl.AuthnRequestImpl;
-import org.opensaml.saml2.metadata.AssertionConsumerService;
-import org.opensaml.saml2.metadata.AttributeConsumingService;
-import org.opensaml.saml2.metadata.EntityDescriptor;
-import org.opensaml.saml2.metadata.NameIDFormat;
-import org.opensaml.saml2.metadata.RequestedAttribute;
-import org.opensaml.saml2.metadata.SPSSODescriptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.Base64Utils;
-
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper;
-import at.gv.egiz.eaaf.core.api.idp.IAuthData;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
-import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface;
-import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
-import at.gv.egiz.eaaf.core.impl.data.Pair;
-import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
-import at.gv.egiz.eaaf.core.impl.utils.Random;
-import at.gv.egiz.eaaf.modules.pvp2.PVPConstants;
-import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.exception.QAANotSupportedException;
-import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator;
-import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException;
-import at.gv.egiz.eaaf.modules.pvp2.idp.exception.UnprovideableAttributeException;
-import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPAttributeBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QAALevelVerifier;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils;
-
-@Service("PVP2AssertionBuilder")
-public class PVP2AssertionBuilder implements PVPConstants {
-
- private static final Logger log = LoggerFactory.getLogger(PVP2AssertionBuilder.class);
- @Autowired private ILoALevelMapper loaLevelMapper;
- @Autowired private ISubjectNameIdGenerator subjectNameIdGenerator;
-
-
- /**
- * Build a PVP assertion as response for a SAML2 AttributeQuery request
- *
- * @param issuerEntityID EnitiyID, which should be used for this IDP response
- * @param attrQuery AttributeQuery request from Service-Provider
- * @param attrList List of PVP response attributes
- * @param now Current time
- * @param validTo ValidTo time of the assertion
- * @param qaaLevel QAA level of the authentication
- * @param sessionIndex SAML2 SessionIndex, which should be included *
- * @return PVP 2.1 Assertion
- * @throws PVP2Exception
- */
- public Assertion buildAssertion(String issuerEntityID, AttributeQuery attrQuery,
- List<Attribute> attrList, DateTime now, DateTime validTo, String qaaLevel, String sessionIndex) throws PVP2Exception {
-
- AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class);
- authnContextClassRef.setAuthnContextClassRef(qaaLevel);
-
- NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
- subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat());
- subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue());
-
- SubjectConfirmationData subjectConfirmationData = null;
-
- return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now,
- authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex,
- validTo);
- }
-
-
- /**
- * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest
- *
- * @param issuerEntityID EnitiyID, which should be used for this IDP response
- * @param pendingReq Current processed pendingRequest DAO
- * @param authnRequest Current processed PVP AuthnRequest
- * @param authData AuthenticationData of the user, which is already authenticated
- * @param peerEntity SAML2 EntityDescriptor of the service-provider, which receives the response
- * @param date TimeStamp
- * @param assertionConsumerService SAML2 endpoint of the service-provider, which should be used
- * @param sloInformation Single LogOut information DAO
- * @return
- * @throws PVP2Exception
- */
- public Assertion buildAssertion(String issuerEntityID, PVPSProfilePendingRequest pendingReq, AuthnRequest authnRequest,
- IAuthData authData, EntityDescriptor peerEntity, DateTime date,
- AssertionConsumerService assertionConsumerService, SLOInformationInterface sloInformation)
- throws PVP2Exception {
-
- ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
- AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class);
-
- //check if authn. request contains LoA
- RequestedAuthnContext reqAuthnContext = authnRequest.getRequestedAuthnContext();
- if (reqAuthnContext == null) {
- authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel());
-
- } else {
- //authn. request requests LoA levels. To LoA validation
- List<AuthnContextClassRef> reqAuthnContextClassRefIt = reqAuthnContext.getAuthnContextClassRefs();
-
- //get matching mode from authn. request
- String loaMatchingMode = EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM;
- if (reqAuthnContext.getComparison() != null &&
- StringUtils.isNotEmpty(reqAuthnContext.getComparison().toString()))
- loaMatchingMode = reqAuthnContext.getComparison().toString();
-
- //get requested LoAs
- if (reqAuthnContextClassRefIt.size() == 0) {
- QAALevelVerifier.verifyQAALevel(authData.getEIDASQAALevel(),
- oaParam.getRequiredLoA(), loaMatchingMode);
- authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel());
-
- } else {
- List<String> eIDASLoaFromRequest = new ArrayList<String>();
- for (AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) {
- String qaa_uri = authnClassRef.getAuthnContextClassRef();
-
- if (!qaa_uri.trim().startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) {
- if (loaLevelMapper != null) {
- log.debug("Find no eIDAS LoA in AuthnReq. Start mapping process ... " );
- eIDASLoaFromRequest.add(loaLevelMapper.mapToeIDASLoA(qaa_uri.trim()));
-
- } else
- log.debug("AuthnRequest contains no eIDAS LoA. NO LoA mapper FOUND, ignore "
- + "'" + qaa_uri.trim() + "'");
- } else
- eIDASLoaFromRequest.add(qaa_uri.trim());
-
- }
-
- //stop process if no supported LoA scheme is requested
- if (eIDASLoaFromRequest.isEmpty()) {
- log.info("Authn. request contains no supported LoA level. Stop authentication process ... ");
- throw new QAANotSupportedException("No supported LoA in Authn. request");
-
- }
-
- //verifiy LoAs from request to authentication LoA
- QAALevelVerifier.verifyQAALevel(authData.getEIDASQAALevel(), eIDASLoaFromRequest , loaMatchingMode);
- authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel());
-
- }
- }
-
-
- //load SPSS decriptor from service-provider metadata
- SPSSODescriptor spSSODescriptor = peerEntity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
-
- //add Attributes to Assertion
- List<Attribute> attrList = new ArrayList<Attribute>();
- if (spSSODescriptor.getAttributeConsumingServices() != null &&
- spSSODescriptor.getAttributeConsumingServices().size() > 0) {
-
- Integer aIdx = authnRequest.getAttributeConsumingServiceIndex();
- int idx = 0;
-
- AttributeConsumingService attributeConsumingService = null;
- if (aIdx != null) {
- idx = aIdx.intValue();
- attributeConsumingService = spSSODescriptor
- .getAttributeConsumingServices().get(idx);
-
- } else {
- List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices();
- for (AttributeConsumingService el : attrConsumingServiceList) {
- if (el.isDefault())
- attributeConsumingService = el;
- }
- }
-
- /*
- * TODO: maybe use first AttributeConsumingService if no is selected
- * in request or on service is marked as default
- *
- */
- if (attributeConsumingService == null ) {
- List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices();
- if (attrConsumingServiceList != null && !attrConsumingServiceList.isEmpty())
- attributeConsumingService = attrConsumingServiceList.get(0);
-
- }
-
-
- if (attributeConsumingService != null) {
- Iterator<RequestedAttribute> it = attributeConsumingService
- .getRequestAttributes().iterator();
- while (it.hasNext()) {
- RequestedAttribute reqAttribut = it.next();
- try {
- Attribute attr = PVPAttributeBuilder.buildAttribute(
- reqAttribut.getName(), oaParam, authData);
- if (attr == null) {
- if (reqAttribut.isRequired()) {
- throw new UnprovideableAttributeException(
- reqAttribut.getName());
- }
- } else {
- attrList.add(attr);
- }
-
- } catch (UnavailableAttributeException e) {
- log.info(
- "Attribute generation for "
- + reqAttribut.getFriendlyName() + " not possible.");
- if (reqAttribut.isRequired()) {
- throw new UnprovideableAttributeException(
- reqAttribut.getName());
- }
-
-
- } catch (PVP2Exception e) {
- log.info(
- "Attribute generation failed! for "
- + reqAttribut.getFriendlyName());
- if (reqAttribut.isRequired()) {
- throw new UnprovideableAttributeException(
- reqAttribut.getName());
- }
-
- } catch (Exception e) {
- log.warn(
- "General Attribute generation failed! for "
- + reqAttribut.getFriendlyName(), e);
- if (reqAttribut.isRequired()) {
- throw new UnprovideableAttributeException(
- reqAttribut.getName());
- }
-
- }
- }
- }
- }
-
- //generate subjectNameId
- NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
- Pair<String, String> subjectNameIdPair = subjectNameIdGenerator.generateSubjectNameId(authData, oaParam);
- subjectNameID.setValue(subjectNameIdPair.getFirst());
- subjectNameID.setNameQualifier(subjectNameIdPair.getSecond());
-
- //get NameIDFormat from request
- String nameIDFormat = NameID.TRANSIENT;
- AuthnRequest authnReq = (AuthnRequestImpl) authnRequest;
- if (authnReq.getNameIDPolicy() != null &&
- StringUtils.isNotEmpty(authnReq.getNameIDPolicy().getFormat())) {
- nameIDFormat = authnReq.getNameIDPolicy().getFormat();
-
- } else {
- //get NameIDFormat from metadata
- List<NameIDFormat> metadataNameIDFormats = spSSODescriptor.getNameIDFormats();
-
- if (metadataNameIDFormats != null) {
-
- for (NameIDFormat el : metadataNameIDFormats) {
- if (NameID.PERSISTENT.equals(el.getFormat())) {
- nameIDFormat = NameID.PERSISTENT;
- break;
-
- } else if (NameID.TRANSIENT.equals(el.getFormat()) ||
- NameID.UNSPECIFIED.equals(el.getFormat()))
- break;
-
- }
- }
- }
-
- if (NameID.TRANSIENT.equals(nameIDFormat) || NameID.UNSPECIFIED.equals(nameIDFormat)) {
- String random = Random.nextHexRandom32();
- String nameID = subjectNameID.getValue();
-
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1"));
- subjectNameID.setValue(Base64Utils.encodeToString(hash));
- subjectNameID.setNameQualifier(null);
- subjectNameID.setFormat(NameID.TRANSIENT);
-
- } catch (Exception e) {
- log.warn("PVP2 subjectNameID error", e);
- throw new ResponderErrorException("internal.03", null, e);
-
- }
-
- } else
- subjectNameID.setFormat(nameIDFormat);
-
-
- String sessionIndex = null;
-
- //if request is a reauthentication and NameIDFormat match reuse old session information
- if (StringUtils.isNotEmpty(authData.getNameID()) &&
- StringUtils.isNotEmpty(authData.getNameIDFormat()) &&
- nameIDFormat.equals(authData.getNameIDFormat())) {
- subjectNameID.setValue(authData.getNameID());
- sessionIndex = authData.getSessionIndex();
-
- }
-
- //
- if (StringUtils.isEmpty(sessionIndex))
- sessionIndex = SAML2Utils.getSecureIdentifier();
-
- SubjectConfirmationData subjectConfirmationData = SAML2Utils
- .createSAMLObject(SubjectConfirmationData.class);
- subjectConfirmationData.setInResponseTo(authnRequest.getID());
- subjectConfirmationData.setNotOnOrAfter(new DateTime(authData.getSsoSessionValidTo().getTime()));
-
- //set 'recipient' attribute in subjectConformationData
- subjectConfirmationData.setRecipient(assertionConsumerService.getLocation());
-
- //set IP address of the user machine as 'Address' attribute in subjectConformationData
- String usersIPAddress = pendingReq.getRawData(
- RequestImpl.DATAID_REQUESTER_IP_ADDRESS, String.class);
- if (StringUtils.isNotEmpty(usersIPAddress))
- subjectConfirmationData.setAddress(usersIPAddress);
-
- //set SLO information
- sloInformation.setUserNameIdentifier(subjectNameID.getValue());
- sloInformation.setNameIDFormat(subjectNameID.getFormat());
- sloInformation.setSessionIndex(sessionIndex);
-
- return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter());
- }
-
- /**
- *
- * @param issuer IDP EntityID
- * @param entityID Service Provider EntityID
- * @param date
- * @param authnContextClassRef
- * @param attrList
- * @param subjectNameID
- * @param subjectConfirmationData
- * @param sessionIndex
- * @param isValidTo
- * @return
- * @throws ConfigurationException
- */
-
- public Assertion buildGenericAssertion(String issuer, String entityID, DateTime date,
- AuthnContextClassRef authnContextClassRef, List<Attribute> attrList,
- NameID subjectNameID, SubjectConfirmationData subjectConfirmationData,
- String sessionIndex, DateTime isValidTo) throws ResponderErrorException {
- Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class);
-
- AuthnContext authnContext = SAML2Utils
- .createSAMLObject(AuthnContext.class);
- authnContext.setAuthnContextClassRef(authnContextClassRef);
-
- AuthnStatement authnStatement = SAML2Utils
- .createSAMLObject(AuthnStatement.class);
-
- authnStatement.setAuthnInstant(date);
- authnStatement.setSessionIndex(sessionIndex);
- authnStatement.setAuthnContext(authnContext);
-
- assertion.getAuthnStatements().add(authnStatement);
-
- AttributeStatement attributeStatement = SAML2Utils
- .createSAMLObject(AttributeStatement.class);
- attributeStatement.getAttributes().addAll(attrList);
- if (attributeStatement.getAttributes().size() > 0) {
- assertion.getAttributeStatements().add(attributeStatement);
- }
-
- Subject subject = SAML2Utils.createSAMLObject(Subject.class);
- subject.setNameID(subjectNameID);
-
- SubjectConfirmation subjectConfirmation = SAML2Utils
- .createSAMLObject(SubjectConfirmation.class);
- subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER);
- subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
-
- subject.getSubjectConfirmations().add(subjectConfirmation);
-
- Conditions conditions = SAML2Utils.createSAMLObject(Conditions.class);
- AudienceRestriction audienceRestriction = SAML2Utils
- .createSAMLObject(AudienceRestriction.class);
- Audience audience = SAML2Utils.createSAMLObject(Audience.class);
-
- audience.setAudienceURI(entityID);
- audienceRestriction.getAudiences().add(audience);
- conditions.setNotBefore(date);
- conditions.setNotOnOrAfter(isValidTo);
-
- conditions.getAudienceRestrictions().add(audienceRestriction);
-
- assertion.setConditions(conditions);
-
- Issuer issuerObj = SAML2Utils.createSAMLObject(Issuer.class);
-
- if (issuer.endsWith("/"))
- issuer = issuer.substring(0, issuer.length()-1);
- issuerObj.setValue(issuer);
- issuerObj.setFormat(NameID.ENTITY);
-
- assertion.setIssuer(issuerObj);
- assertion.setSubject(subject);
- assertion.setID(SAML2Utils.getSecureIdentifier());
- assertion.setIssueInstant(date);
-
- return assertion;
- }
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java
new file mode 100644
index 00000000..b7b18f0f
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/Pvp2AssertionBuilder.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder;
+
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.ConfigurationException;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
+import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.exception.QaaNotSupportedException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.UnprovideableAttributeException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QaaLevelVerifier;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.Attribute;
+import org.opensaml.saml.saml2.core.AttributeQuery;
+import org.opensaml.saml.saml2.core.AttributeStatement;
+import org.opensaml.saml.saml2.core.Audience;
+import org.opensaml.saml.saml2.core.AudienceRestriction;
+import org.opensaml.saml.saml2.core.AuthnContext;
+import org.opensaml.saml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.AuthnStatement;
+import org.opensaml.saml.saml2.core.Conditions;
+import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.NameID;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.core.RequestedAuthnContext;
+import org.opensaml.saml.saml2.core.Subject;
+import org.opensaml.saml.saml2.core.SubjectConfirmation;
+import org.opensaml.saml.saml2.core.SubjectConfirmationData;
+import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml.saml2.metadata.AttributeConsumingService;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.NameIDFormat;
+import org.opensaml.saml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Base64Utils;
+
+@Service("PVP2AssertionBuilder")
+public class Pvp2AssertionBuilder implements PvpConstants {
+
+ private static final Logger log = LoggerFactory.getLogger(Pvp2AssertionBuilder.class);
+ @Autowired
+ private ILoALevelMapper loaLevelMapper;
+ @Autowired
+ private ISubjectNameIdGenerator subjectNameIdGenerator;
+
+ /**
+ * Build a PVP assertion as response for a SAML2 AttributeQuery request.
+ *
+ * @param issuerEntityID EnitiyID, which should be used for this IDP response
+ * @param attrQuery AttributeQuery request from Service-Provider
+ * @param attrList List of PVP response attributes
+ * @param now Current time
+ * @param validTo ValidTo time of the assertion
+ * @param qaaLevel QAA level of the authentication
+ * @param sessionIndex SAML2 SessionIndex, which should be included *
+ * @return PVP 2.1 Assertion
+ * @throws Pvp2Exception In case of an error
+ */
+ public Assertion buildAssertion(final String issuerEntityID, final AttributeQuery attrQuery,
+ final List<Attribute> attrList, final DateTime now, final DateTime validTo,
+ final String qaaLevel, final String sessionIndex) throws Pvp2Exception {
+
+ final AuthnContextClassRef authnContextClassRef =
+ Saml2Utils.createSamlObject(AuthnContextClassRef.class);
+ authnContextClassRef.setAuthnContextClassRef(qaaLevel);
+
+ final NameID subjectNameID = Saml2Utils.createSamlObject(NameID.class);
+ subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat());
+ subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue());
+
+ final SubjectConfirmationData subjectConfirmationData = null;
+
+ return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now,
+ authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex,
+ validTo);
+ }
+
+ /**
+ * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest.
+ *
+ * @param issuerEntityID EnitiyID, which should be used for this IDP
+ * response
+ * @param pendingReq Current processed pendingRequest DAO
+ * @param authnRequest Current processed PVP AuthnRequest
+ * @param authData AuthenticationData of the user, which is
+ * already authenticated
+ * @param peerEntity SAML2 EntityDescriptor of the
+ * service-provider, which receives the response
+ * @param date TimeStamp
+ * @param assertionConsumerService SAML2 endpoint of the service-provider, which
+ * should be used
+ * @param sloInformation Single LogOut information DAO
+ * @return PVP2 S-Profil Assertion
+ * @throws Pvp2Exception In case of an error
+ */
+ public Assertion buildAssertion(final String issuerEntityID,
+ final PvpSProfilePendingRequest pendingReq, final AuthnRequest authnRequest,
+ final IAuthData authData, final EntityDescriptor peerEntity, final DateTime date,
+ final AssertionConsumerService assertionConsumerService,
+ final SloInformationInterface sloInformation) throws Pvp2Exception {
+
+ final ISpConfiguration oaParam = pendingReq.getServiceProviderConfiguration();
+ final AuthnContextClassRef authnContextClassRef =
+ Saml2Utils.createSamlObject(AuthnContextClassRef.class);
+
+ // check if authn. request contains LoA
+ final RequestedAuthnContext reqAuthnContext = authnRequest.getRequestedAuthnContext();
+ if (reqAuthnContext == null) {
+ authnContextClassRef.setAuthnContextClassRef(authData.getEidasQaaLevel());
+
+ } else {
+ // authn. request requests LoA levels. To LoA validation
+ final List<AuthnContextClassRef> reqAuthnContextClassRefIt =
+ reqAuthnContext.getAuthnContextClassRefs();
+
+ // get matching mode from authn. request
+ String loaMatchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM;
+ if (reqAuthnContext.getComparison() != null
+ && StringUtils.isNotEmpty(reqAuthnContext.getComparison().toString())) {
+ loaMatchingMode = reqAuthnContext.getComparison().toString();
+ }
+
+ // get requested LoAs
+ if (reqAuthnContextClassRefIt.size() == 0) {
+ QaaLevelVerifier.verifyQaaLevel(authData.getEidasQaaLevel(), oaParam.getRequiredLoA(),
+ loaMatchingMode);
+ authnContextClassRef.setAuthnContextClassRef(authData.getEidasQaaLevel());
+
+ } else {
+ final List<String> eidasLoaFromRequest = new ArrayList<>();
+ for (final AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) {
+ final String qaa_uri = authnClassRef.getAuthnContextClassRef();
+
+ if (!qaa_uri.trim().startsWith(EaafConstants.EIDAS_LOA_PREFIX)) {
+ if (loaLevelMapper != null) {
+ log.debug("Find no eIDAS LoA in AuthnReq. Start mapping process ... ");
+ eidasLoaFromRequest.add(loaLevelMapper.mapToEidasLoa(qaa_uri.trim()));
+
+ } else {
+ log.debug("AuthnRequest contains no eIDAS LoA. NO LoA mapper FOUND, ignore " + "'"
+ + qaa_uri.trim() + "'");
+ }
+ } else {
+ eidasLoaFromRequest.add(qaa_uri.trim());
+ }
+
+ }
+
+ // stop process if no supported LoA scheme is requested
+ if (eidasLoaFromRequest.isEmpty()) {
+ log.info(
+ "Authn. request contains no supported LoA level. Stop authentication process ... ");
+ throw new QaaNotSupportedException("No supported LoA in Authn. request");
+
+ }
+
+ // verifiy LoAs from request to authentication LoA
+ QaaLevelVerifier.verifyQaaLevel(authData.getEidasQaaLevel(), eidasLoaFromRequest,
+ loaMatchingMode);
+ authnContextClassRef.setAuthnContextClassRef(authData.getEidasQaaLevel());
+
+ }
+ }
+
+ // load SPSS decriptor from service-provider metadata
+ final SPSSODescriptor spSsoDescriptor = peerEntity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+
+ // add Attributes to Assertion
+ final List<Attribute> attrList = new ArrayList<>();
+ if (spSsoDescriptor.getAttributeConsumingServices() != null
+ && spSsoDescriptor.getAttributeConsumingServices().size() > 0) {
+
+ final Integer aIdx = authnRequest.getAttributeConsumingServiceIndex();
+ int idx = 0;
+
+ AttributeConsumingService attributeConsumingService = null;
+ if (aIdx != null) {
+ idx = aIdx;
+ attributeConsumingService = spSsoDescriptor.getAttributeConsumingServices().get(idx);
+
+ } else {
+ final List<AttributeConsumingService> attrConsumingServiceList =
+ spSsoDescriptor.getAttributeConsumingServices();
+ for (final AttributeConsumingService el : attrConsumingServiceList) {
+ if (el.isDefault()) {
+ attributeConsumingService = el;
+ }
+ }
+ }
+
+ /*
+ * TODO: maybe use first AttributeConsumingService if no is selected in request
+ * or on service is marked as default
+ *
+ */
+ if (attributeConsumingService == null) {
+ final List<AttributeConsumingService> attrConsumingServiceList =
+ spSsoDescriptor.getAttributeConsumingServices();
+ if (attrConsumingServiceList != null && !attrConsumingServiceList.isEmpty()) {
+ attributeConsumingService = attrConsumingServiceList.get(0);
+ }
+
+ }
+
+ if (attributeConsumingService != null) {
+ final Iterator<RequestedAttribute> it =
+ attributeConsumingService.getRequestAttributes().iterator();
+ while (it.hasNext()) {
+ final RequestedAttribute reqAttribut = it.next();
+ try {
+ final Attribute attr =
+ PvpAttributeBuilder.buildAttribute(reqAttribut.getName(), oaParam, authData);
+ if (attr == null) {
+ if (reqAttribut.isRequired()) {
+ throw new UnprovideableAttributeException(reqAttribut.getName());
+ }
+ } else {
+ attrList.add(attr);
+ }
+
+ } catch (final UnavailableAttributeException e) {
+ log.info(
+ "Attribute generation for " + reqAttribut.getFriendlyName() + " not possible.");
+ if (reqAttribut.isRequired()) {
+ throw new UnprovideableAttributeException(reqAttribut.getName());
+ }
+
+ } catch (final Pvp2Exception e) {
+ log.info("Attribute generation failed! for " + reqAttribut.getFriendlyName());
+ if (reqAttribut.isRequired()) {
+ throw new UnprovideableAttributeException(reqAttribut.getName());
+ }
+
+ } catch (final Exception e) {
+ log.warn("General Attribute generation failed! for " + reqAttribut.getFriendlyName(),
+ e);
+ if (reqAttribut.isRequired()) {
+ throw new UnprovideableAttributeException(reqAttribut.getName());
+ }
+
+ }
+ }
+ }
+ }
+
+ // generate subjectNameId
+ final NameID subjectNameID = Saml2Utils.createSamlObject(NameID.class);
+ final Pair<String, String> subjectNameIdPair =
+ subjectNameIdGenerator.generateSubjectNameId(authData, oaParam);
+ subjectNameID.setValue(subjectNameIdPair.getFirst());
+ subjectNameID.setNameQualifier(subjectNameIdPair.getSecond());
+
+ // get NameIDFormat from request
+ String nameIdFormat = NameIDType.TRANSIENT;
+ final AuthnRequest authnReq = authnRequest;
+ if (authnReq.getNameIDPolicy() != null
+ && StringUtils.isNotEmpty(authnReq.getNameIDPolicy().getFormat())) {
+ nameIdFormat = authnReq.getNameIDPolicy().getFormat();
+
+ } else {
+ // get NameIDFormat from metadata
+ final List<NameIDFormat> metadataNameIdFormats = spSsoDescriptor.getNameIDFormats();
+
+ if (metadataNameIdFormats != null) {
+
+ for (final NameIDFormat el : metadataNameIdFormats) {
+ if (NameIDType.PERSISTENT.equals(el.getFormat())) {
+ nameIdFormat = NameIDType.PERSISTENT;
+ break;
+
+ } else if (NameIDType.TRANSIENT.equals(el.getFormat())
+ || NameIDType.UNSPECIFIED.equals(el.getFormat())) {
+ break;
+ }
+
+ }
+ }
+ }
+
+ if (NameIDType.TRANSIENT.equals(nameIdFormat) || NameIDType.UNSPECIFIED.equals(nameIdFormat)) {
+ final String random = Random.nextHexRandom32();
+ final String nameID = subjectNameID.getValue();
+
+ try {
+ final MessageDigest md = MessageDigest.getInstance("SHA-1");
+ final byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1"));
+ subjectNameID.setValue(Base64Utils.encodeToString(hash));
+ subjectNameID.setNameQualifier(null);
+ subjectNameID.setFormat(NameIDType.TRANSIENT);
+
+ } catch (final Exception e) {
+ log.warn("PVP2 subjectNameID error", e);
+ throw new ResponderErrorException("internal.03", null, e);
+
+ }
+
+ } else {
+ subjectNameID.setFormat(nameIdFormat);
+ }
+
+ String sessionIndex = null;
+
+ // if request is a reauthentication and NameIDFormat match reuse old session
+ // information
+ if (StringUtils.isNotEmpty(authData.getNameID())
+ && StringUtils.isNotEmpty(authData.getNameIdFormat())
+ && nameIdFormat.equals(authData.getNameIdFormat())) {
+ subjectNameID.setValue(authData.getNameID());
+ sessionIndex = authData.getSessionIndex();
+
+ }
+
+ //
+ if (StringUtils.isEmpty(sessionIndex)) {
+ sessionIndex = Saml2Utils.getSecureIdentifier();
+ }
+
+ final SubjectConfirmationData subjectConfirmationData =
+ Saml2Utils.createSamlObject(SubjectConfirmationData.class);
+ subjectConfirmationData.setInResponseTo(authnRequest.getID());
+ subjectConfirmationData
+ .setNotOnOrAfter(new DateTime(authData.getSsoSessionValidTo().getTime()));
+
+ // set 'recipient' attribute in subjectConformationData
+ subjectConfirmationData.setRecipient(assertionConsumerService.getLocation());
+
+ // set IP address of the user machine as 'Address' attribute in
+ // subjectConformationData
+ final String usersIpAddress =
+ pendingReq.getRawData(RequestImpl.DATAID_REQUESTER_IP_ADDRESS, String.class);
+ if (StringUtils.isNotEmpty(usersIpAddress)) {
+ subjectConfirmationData.setAddress(usersIpAddress);
+ }
+
+ // set SLO information
+ sloInformation.setUserNameIdentifier(subjectNameID.getValue());
+ sloInformation.setNameIdFormat(subjectNameID.getFormat());
+ sloInformation.setSessionIndex(sessionIndex);
+
+ return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date,
+ authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex,
+ subjectConfirmationData.getNotOnOrAfter());
+ }
+
+ /**
+ * Build generic part of PVP S-Profile Assertion.
+ *
+ * @param issuer IDP EntityID
+ * @param entityID Service Provider EntityID
+ * @param date Timestamp
+ * @param authnContextClassRef SAML2 AuthnContextClassReference
+ * @param attrList List of attributes
+ * @param subjectNameID SubjectNameId
+ * @param subjectConfirmationData SubjectConfirmationInformation
+ * @param sessionIndex SessionIndex
+ * @param isValidTo ValidTo Timestamp
+ * @return PVP S-Profile Assertion
+ * @throws ConfigurationException In case on an error
+ */
+
+ public Assertion buildGenericAssertion(String issuer, final String entityID, final DateTime date,
+ final AuthnContextClassRef authnContextClassRef, final List<Attribute> attrList,
+ final NameID subjectNameID, final SubjectConfirmationData subjectConfirmationData,
+ final String sessionIndex, final DateTime isValidTo) throws ResponderErrorException {
+ final Assertion assertion = Saml2Utils.createSamlObject(Assertion.class);
+
+ final AuthnContext authnContext = Saml2Utils.createSamlObject(AuthnContext.class);
+ authnContext.setAuthnContextClassRef(authnContextClassRef);
+
+ final AuthnStatement authnStatement = Saml2Utils.createSamlObject(AuthnStatement.class);
+
+ authnStatement.setAuthnInstant(date);
+ authnStatement.setSessionIndex(sessionIndex);
+ authnStatement.setAuthnContext(authnContext);
+
+ assertion.getAuthnStatements().add(authnStatement);
+
+ final AttributeStatement attributeStatement =
+ Saml2Utils.createSamlObject(AttributeStatement.class);
+ attributeStatement.getAttributes().addAll(attrList);
+ if (attributeStatement.getAttributes().size() > 0) {
+ assertion.getAttributeStatements().add(attributeStatement);
+ }
+
+ final Subject subject = Saml2Utils.createSamlObject(Subject.class);
+ subject.setNameID(subjectNameID);
+
+ final SubjectConfirmation subjectConfirmation =
+ Saml2Utils.createSamlObject(SubjectConfirmation.class);
+ subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER);
+ subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
+
+ subject.getSubjectConfirmations().add(subjectConfirmation);
+
+ final Conditions conditions = Saml2Utils.createSamlObject(Conditions.class);
+ final AudienceRestriction audienceRestriction =
+ Saml2Utils.createSamlObject(AudienceRestriction.class);
+ final Audience audience = Saml2Utils.createSamlObject(Audience.class);
+
+ audience.setAudienceURI(entityID);
+ audienceRestriction.getAudiences().add(audience);
+ conditions.setNotBefore(date);
+ conditions.setNotOnOrAfter(isValidTo);
+
+ conditions.getAudienceRestrictions().add(audienceRestriction);
+
+ assertion.setConditions(conditions);
+
+ final Issuer issuerObj = Saml2Utils.createSamlObject(Issuer.class);
+
+ if (issuer.endsWith("/")) {
+ issuer = issuer.substring(0, issuer.length() - 1);
+ }
+ issuerObj.setValue(issuer);
+ issuerObj.setFormat(NameIDType.ENTITY);
+
+ assertion.setIssuer(issuerObj);
+ assertion.setSubject(subject);
+ assertion.setID(Saml2Utils.getSecureIdentifier());
+ assertion.setIssueInstant(date);
+
+ return assertion;
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
index cda12a62..c3c68e20 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
@@ -1 +1 @@
-at.gv.egiz.eaaf.modules.pvp2.idp.PVP2SProfileIDPSpringResourceProvider \ No newline at end of file
+at.gv.egiz.eaaf.modules.pvp2.idp.Pvp2SProfileIdpSpringResourceProvider \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml
index b01a09ff..d29b5aba 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/resources/eaaf_pvp_idp.beans.xml
@@ -1,22 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--
- -->
-
<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
- <bean id="PVP2AssertionBuilder"
- class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.PVP2AssertionBuilder" />
-
- <bean id="PVPSProfilePendingRequest"
- class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest"
- scope="prototype"/>
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
+
+ <bean id="PVP2AssertionBuilder"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.Pvp2AssertionBuilder" />
+
+ <bean id="PVPSProfilePendingRequest"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest"
+ scope="prototype" />
+
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java
new file mode 100644
index 00000000..a88fa869
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java
@@ -0,0 +1,226 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import java.util.Date;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.AuthenticationAction;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
+@TestPropertySource(
+ locations = {"/config/config_1.props"})
+public class AuthenticationActionTest {
+
+ @Autowired private DummyAuthConfig authConfig;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private AuthenticationAction action;
+
+ protected MockHttpServletRequest httpReq;
+ protected MockHttpServletResponse httpResp;
+ private PvpSProfilePendingRequest pendingReq;
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Test initializer.
+ *
+ */
+ @Before
+ public void initialize() {
+ httpReq = new MockHttpServletRequest();
+ httpResp = new MockHttpServletResponse();
+
+ pendingReq = new PvpSProfilePendingRequest();
+
+ }
+
+ @Test
+ public void checkNeedAuthFlag() {
+ Assert.assertTrue("Wrong 'needAuth' flag", action.needAuthentication(pendingReq, httpReq, httpResp));
+
+ }
+
+ @Test
+ public void noAuthnRequestInPendingRequest() {
+
+ IAuthData authData = generateAuthData();
+
+ try {
+ action.processRequest(pendingReq, httpReq, httpResp, authData);
+ Assert.fail("No SAML requst not detected");
+
+ } catch (ResponderErrorException e) {
+ Assert.assertEquals("Wrong errorCode", "pvp2.01", e.getErrorId());
+ }
+
+ }
+
+ private IAuthData generateAuthData() {
+ return new IAuthData() {
+
+ @Override
+ public boolean isSsoSession() {
+ return false;
+ }
+
+ @Override
+ public boolean isForeigner() {
+ return false;
+ }
+
+ @Override
+ public boolean isBaseIdTransferRestrication() {
+ return true;
+ }
+
+ @Override
+ public Date getSsoSessionValidTo() {
+ return null;
+
+ }
+
+ @Override
+ public String getSessionIndex() {
+ return null;
+
+ }
+
+ @Override
+ public String getNameIdFormat() {
+ return null;
+
+ }
+
+ @Override
+ public String getNameID() {
+ return null;
+
+ }
+
+ @Override
+ public IIdentityLink getIdentityLink() {
+ return null;
+
+ }
+
+ @Override
+ public String getIdentificationValue() {
+ return null;
+
+ }
+
+ @Override
+ public String getIdentificationType() {
+ return null;
+
+ }
+
+ @Override
+ public String getGivenName() {
+ return RandomStringUtils.randomAlphabetic(10);
+
+ }
+
+ @Override
+ public <T> T getGenericData(String key, Class<T> clazz) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getFormatedDateOfBirth() {
+ return DateFormatUtils.format(getDateOfBirth(), "yyyy-MM-dd");
+ }
+
+ @Override
+ public String getFamilyName() {
+ return RandomStringUtils.randomAlphabetic(10);
+
+ }
+
+ @Override
+ public String getEncryptedSourceIdType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getEncryptedSourceId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getEidasQaaLevel() {
+ return EaafConstants.EIDAS_LOA_LOW;
+ }
+
+ @Override
+ public Date getDateOfBirth() {
+ return new Date();
+
+ }
+
+ @Override
+ public String getCiticenCountryCode() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getBpkType() {
+ return EaafConstants.URN_PREFIX_CDID + RandomStringUtils.randomAlphabetic(2);
+ }
+
+ @Override
+ public String getBpk() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getAuthenticationIssuer() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getAuthenticationIssueInstantString() {
+ return DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(getAuthenticationIssueInstant());
+ }
+
+ @Override
+ public Date getAuthenticationIssueInstant() {
+ return new Date();
+ }
+ };
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java
new file mode 100644
index 00000000..b2e528c4
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java
@@ -0,0 +1,156 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import java.io.IOException;
+
+import javax.xml.transform.TransformerException;
+
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.AuthResponseBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
+import at.gv.egiz.eaaf.modules.pvp2.test.binding.PostBindingTest;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.joda.time.DateTime;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.RequestAbstractType;
+import org.opensaml.saml.saml2.core.Response;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.w3c.dom.Element;
+
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
+@TestPropertySource(
+ locations = {"/config/config_1.props"})
+public class AuthnResponseBuilderTest {
+
+ @Autowired private DummyAuthConfig authConfig;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private SamlVerificationEngine verifyEngine;
+ @Autowired private DummyCredentialProvider credentialProvider;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ @Test
+ public void encryptedAssertion() throws InvalidAssertionEncryptionException, Pvp2MetadataException,
+ XMLParserException, UnmarshallingException, MarshallingException, TransformerException, IOException {
+ final String issuerEntityID = RandomStringUtils.randomAlphabetic(15);
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"));
+ authnReq.setID("_" + RandomStringUtils.randomAlphanumeric(10));
+
+ final Assertion assertion = (Assertion) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/Assertion_1.xml"));
+
+ //build response
+ final DateTime now = DateTime.now();
+ final Response response = AuthResponseBuilder.buildResponse(
+ metadataProvider, issuerEntityID, authnReq,
+ now, assertion, authConfig);
+
+
+ //validate
+ Assert.assertNotNull("SAML2 response is null", response);
+ Assert.assertTrue("Assertion not null", response.getAssertions().isEmpty());
+ Assert.assertNotNull("Enc. assertion is null", response.getEncryptedAssertions());
+ Assert.assertFalse("Enc. assertion is empty", response.getEncryptedAssertions().isEmpty());
+ Assert.assertEquals("# enc. assertions wrong", 1, response.getEncryptedAssertions().size());
+
+ Assert.assertEquals("InResponseTo", authnReq.getID(), response.getInResponseTo());
+ Assert.assertEquals("Issuer EntityId", issuerEntityID, response.getIssuer().getValue());
+ Assert.assertNotNull("ResponseId is null", response.getID());
+ Assert.assertFalse("ResponseId is emptry", response.getID().isEmpty());
+
+ final Element responseElement = XMLObjectSupport.getMarshaller(response).marshall(response);
+ final String xmlResp = DomUtils.serializeNode(responseElement);
+ Assert.assertNotNull("XML response is null", xmlResp);
+ Assert.assertFalse("XML response is empty", xmlResp.isEmpty());
+
+ }
+
+ @Test
+ public void encryptedAssertionWithDecryption() throws InvalidAssertionEncryptionException, Pvp2MetadataException,
+ XMLParserException, UnmarshallingException, MarshallingException, TransformerException, IOException,
+ SamlAssertionValidationExeption, CredentialsNotAvailableException {
+ final String issuerEntityID = RandomStringUtils.randomAlphabetic(15);
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"));
+ authnReq.setID("_" + RandomStringUtils.randomAlphanumeric(10));
+
+ final Assertion assertion = (Assertion) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/Assertion_1.xml"));
+
+ //build response
+ final DateTime now = DateTime.now();
+ final Response response = AuthResponseBuilder.buildResponse(
+ metadataProvider, issuerEntityID, authnReq,
+ now, assertion, authConfig);
+
+
+ //validate
+ Assert.assertNotNull("SAML2 response is null", response);
+ Assert.assertTrue("Assertion not null", response.getAssertions().isEmpty());
+ Assert.assertNotNull("Enc. assertion is null", response.getEncryptedAssertions());
+ Assert.assertFalse("Enc. assertion is empty", response.getEncryptedAssertions().isEmpty());
+ Assert.assertEquals("# enc. assertions wrong", 1, response.getEncryptedAssertions().size());
+
+ Assert.assertEquals("InResponseTo", authnReq.getID(), response.getInResponseTo());
+ Assert.assertEquals("Issuer EntityId", issuerEntityID, response.getIssuer().getValue());
+ Assert.assertNotNull("ResponseId is null", response.getID());
+ Assert.assertFalse("ResponseId is emptry", response.getID().isEmpty());
+
+ final Element responseElement = XMLObjectSupport.getMarshaller(response).marshall(response);
+ final String xmlResp = DomUtils.serializeNode(responseElement);
+ Assert.assertNotNull("XML response is null", xmlResp);
+ Assert.assertFalse("XML response is empty", xmlResp.isEmpty());
+
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ "https://demo.egiz.gv.at/demoportal_demologin/", "jUnitTest", false);
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java
new file mode 100644
index 00000000..8436a43d
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java
@@ -0,0 +1,67 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.MetadataAction;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
+@TestPropertySource(
+ locations = {"/config/config_1.props"})
+public class MetadataActionTest {
+
+ @Autowired private DummyAuthConfig authConfig;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private SamlVerificationEngine verifyEngine;
+ @Autowired private DummyCredentialProvider credentialProvider;
+ @Autowired private MetadataAction action;
+
+ protected MockHttpServletRequest httpReq;
+ protected MockHttpServletResponse httpResp;
+ private TestRequestImpl pendingReq;
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Test initializer.
+ *
+ */
+ @Before
+ public void initialize() {
+ httpReq = new MockHttpServletRequest();
+ httpResp = new MockHttpServletResponse();
+
+ pendingReq = new TestRequestImpl();
+
+ }
+
+ @Test
+ public void checkNeedAuthFlag() {
+ Assert.assertFalse("Wrong 'needAuth' flag", action.needAuthentication(pendingReq, httpReq, httpResp));
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java
new file mode 100644
index 00000000..f9aafea9
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java
@@ -0,0 +1,56 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.eaaf.core.test.TestConstants;
+import at.gv.egiz.eaaf.modules.pvp2.idp.Pvp2SProfileIdpSpringResourceProvider;
+
+
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class Pvp2SProfileIdpSpringResourceProviderTest {
+
+ @Test
+ public void testSpringConfig() {
+ final Pvp2SProfileIdpSpringResourceProvider test =
+ new Pvp2SProfileIdpSpringResourceProvider();
+ for (final Resource el : test.getResourcesToLoad()) {
+ try {
+ IOUtils.toByteArray(el.getInputStream());
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + el.getFilename() + " not found");
+ }
+
+ }
+
+ Assert.assertNotNull("no Name", test.getName());
+ Assert.assertNull("Find package definitions", test.getPackagesToScan());
+
+ }
+
+ @Test
+ public void testSpILoaderConfig() {
+ final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH);
+ try {
+ final String spiFile = IOUtils.toString(el, "UTF-8");
+
+ Assert.assertEquals("Wrong classpath in SPI file",
+ Pvp2SProfileIdpSpringResourceProvider.class.getName(), spiFile);
+
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found");
+
+ }
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java
new file mode 100644
index 00000000..004df86d
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java
@@ -0,0 +1,25 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper;
+
+public class DummyLoALevelMapper implements ILoALevelMapper {
+
+ @Override
+ public String mapToEidasLoa(String qaa) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String mapToSecClass(String qaa) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String mapEidasQaaToStorkQaa(String eidasqaaLevel) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java
new file mode 100644
index 00000000..c5fc0f13
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java
@@ -0,0 +1,52 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration;
+
+import org.opensaml.saml.saml2.metadata.ContactPerson;
+import org.opensaml.saml.saml2.metadata.Organization;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DummyPvpConfiguration implements IPvp2BasicConfiguration {
+
+ @Autowired private IConfiguration basicConfig;
+
+ @Override
+ public String getIdpEntityId(String authUrl) throws EaafException {
+ return authUrl + "/idp";
+ }
+
+ @Override
+ public String getIdpSsoPostService(String authUrl) throws EaafException {
+ return authUrl + "/sso/post";
+ }
+
+ @Override
+ public String getIdpSsoRedirectService(String authUrl) throws EaafException {
+ return authUrl + "/sso/redirect";
+ }
+
+ @Override
+ public String getIdpSsoSoapService(String authUrl) throws EaafException {
+ return authUrl + "/sso/soap";
+ }
+
+ @Override
+ public List<ContactPerson> getIdpContacts() throws EaafException {
+ return null;
+ }
+
+ @Override
+ public Organization getIdpOrganisation() throws EaafException {
+ return null;
+ }
+
+ @Override
+ public IConfiguration getBasicConfiguration() {
+ return basicConfig;
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java
new file mode 100644
index 00000000..3f24480b
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataBuilderTest;
+
+public class DummyPvpMetadataConfigFactory implements IPvpMetadataConfigurationFactory {
+
+ @Override
+ public IPvpMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authUrl,
+ IPvp2CredentialProvider pvpIdpCredentials) {
+ return MetadataBuilderTest.idpMetadataConfig(pvpIdpCredentials, false, true);
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java
new file mode 100644
index 00000000..3eaa4c09
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java
@@ -0,0 +1,18 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator;
+
+public class DummySubjectNameGenerator implements ISubjectNameIdGenerator {
+
+ @Override
+ public Pair<String, String> generateSubjectNameId(IAuthData authData, ISpConfiguration spConfig)
+ throws Pvp2Exception {
+ return Pair.newInstance(authData.getBpk(), authData.getBpkType());
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props
new file mode 100644
index 00000000..164b8807
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props
@@ -0,0 +1,12 @@
+keystore.path=classpath:/data/junit.jks
+keystore.pass=password
+key.metadata.alias=meta
+key.metadata.pass=password
+key.sig.alias=sig
+key.sig.pass=password
+key.enc.alias=
+key.enc.pass=
+
+client.http.connection.timeout.socket=2
+client.http.connection.timeout.connection=2
+client.http.connection.timeout.request=2 \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props
new file mode 100644
index 00000000..60cecebb
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props
@@ -0,0 +1,12 @@
+keystore.path=classpath:/data/junit.jks
+keystore.pass=password
+key.metadata.alias=shibboleth-sign
+key.metadata.pass=password
+key.sig.alias=shibboleth-sign
+key.sig.pass=password
+key.enc.alias=
+key.enc.pass=
+
+client.http.connection.timeout.socket=2
+client.http.connection.timeout.connection=2
+client.http.connection.timeout.request=2 \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/Assertion_1.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/Assertion_1.xml
new file mode 100644
index 00000000..7c45b5fa
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/Assertion_1.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_602c3236bffaf71ac3ac88674e76ff9f" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0">
+ <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata</saml2:Issuer>
+ <saml2:Subject>
+ <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="urn:publicid:gv.at:cdid+BF">QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:NameID>
+ <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml2:SubjectConfirmationData InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" NotOnOrAfter="2014-03-05T06:44:51.017Z" Recipient="https://demo.egiz.gv.at/demoportal_demologin/securearea.action"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2014-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://demo.egiz.gv.at/demoportal_demologin/</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://www.stork.gov.eu/1.0/citizenQAALevel/4</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <saml2:Attribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2.1</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Mustermann</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Max</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1940-01-01</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">BF:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-CITIZEN-QAA-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.94" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:integer">4</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="urn:oid:1.2.40.0.10.2.1.1.261.34" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">urn:publicid:gv.at:cdid+BF</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/AuthRequest_without_sig_1.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/AuthRequest_without_sig_1.xml
new file mode 100644
index 00000000..ef35ea92
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/AuthRequest_without_sig_1.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceIndex="1" AttributeConsumingServiceIndex="0" Destination="https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post" ID="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:02.775Z" Version="2.0">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_demologin/</saml2:Issuer>
+ <saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
+ <saml2:NameID>https://demo.egiz.gv.at/demoportal_demologin/</saml2:NameID>
+ </saml2:Subject>
+ <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
+ <saml2p:RequestedAuthnContext>
+ <saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.stork.gov.eu/1.0/citizenQAALevel/4</saml2:AuthnContextClassRef>
+ </saml2p:RequestedAuthnContext>
+</saml2p:AuthnRequest>
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/junit.jks b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/junit.jks
new file mode 100644
index 00000000..b5262cb8
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/junit.jks
Binary files differ
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml
new file mode 100644
index 00000000..7fdbef90
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_2e23ca9b2ba4dc9eef15187830d07ff0" entityID="https://demo.egiz.gv.at/demoportal_demologin/" validUntil="2045-02-05T06:41:42.966Z">
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo>
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="#_2e23ca9b2ba4dc9eef15187830d07ff0">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue>Jy/c0ZvVJSfWzSoAcxDx/o+T5W61vvNJNqTFz2o+ILc=</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>chMxIdwrPvr78j3oTtgS7udbydy9kye1bbeQ4jm2GeFKUfxvJqY+vt9MjVnWFeR4c16gd80BjZJ6xxD5i5Ifci3YtxeKSxq0ttH/xZYEhJZkD/0NrGUhSvNV9zuLAz3uGk/LJ+2JxRq7dbnW4n9MtGuYhea8OW9/Pr1xI1KyskQS76NZDsGjjfnFWbFXahLoQZULU4Ke3SfZVqLATTn0J34RZnjNH3QieY3LhRzOVu/I5yeZtnLgUS6dg0Gab9DA/pdNFaC632iaE5QCXJmhgpqkjbkayO9e8N93YGFjbszhU1Kws5OUGjXjfCZwezLeOUZoKEfo5c+4+zEaTrEQjg==</ds:SignatureValue>
+ <ds:KeyInfo>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIDKzCCAhMCBFrxKO4wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxGDAWBgNVBAsMD2RlbW8uZWdpei5ndi5hdDEiMCAGA1UEAwwZTU9BLUlEIElEUCAoVGVzdC1W
+ZXJzaW9uKTAeFw0xODA1MDgwNDM0NTRaFw0yMTAxMzEwNDM0NTRaMFoxCzAJBgNVBAYTAkFUMQ0w
+CwYDVQQKDARFR0laMRgwFgYDVQQLDA9kZW1vLmVnaXouZ3YuYXQxIjAgBgNVBAMMGU1PQS1JRCBJ
+RFAgKFRlc3QtVmVyc2lvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaFnqoaYoq
+UptenemC6FiVDg5F2hEjpjix8+ow6/6QhUl2cPOS0uwZHaIvwT/RVbJ9CPdil6+11qaCPfZ+FoY+
+M+ke7TRd2RS1DqFbe1KC0imEnwemyLQrYe5Pm7DNcaY/kHTTq+k0eeGbYH0U/Iopyi0VuN5OWl4F
+Vg45pf7knhXkaimItdjnCXnKcYM91mmltCf6TDgUrz7US7PmgvinnhfBgdITAT4GRr4ehliT+/jt
+1OzHEyWRHanBGIpXNeZNqxgnpnGtaDh4JZuYR8qfH+GRK6dtW2ziej6rGIiUElGVCkXsohgxMNzq
+nWeD9JT8+yyp1XZlyQf+IxhhESQLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIFejAFQepaEl/kC
+VLvidMR+MXq5LCGHthUiI6eDTQZ+H7lZdHlj547XwEdX15b6Md3h7eSJ4hwlfV4go/0FaoLPzvVq
+itwtYY5htywB3B6ZV34Eyi6C59Gl34XrV8CWxH4KKwLsVAjAy+/p/Xh0q2pzSBkeOChzBMBkjmyc
+2Ue4MEKdL9guzp6+Yc/HL/phHAKYapkVyFwvsdqWOgyRzxAHINko8ExImMMB3xB5a52kfqLcui5O
+fzEhjwLFJaGBMmFCmFGGOUwtIvl/6ZQ2LLzOE9+giVK9WsIgH11Pu+ejPFAbXf8cf4oWhbAfTkiy
+4jpXrp77JXFRSDWddb0yePc=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </ds:Signature>
+ <md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==</ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIBbTCCARKgAwIBAgIEXjF+qTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJBVDEN
+MAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcw
+HhcNMjAwMTI5MTI0NjMzWhcNMjcwMTI4MTI0NjMzWjA+MQswCQYDVQQGEwJBVDEN
+MAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcw
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASRt7gZRrr4rSEE7Q922oKQJF+mlkwC
+LZnv8ZzHtH54s4VdyQFIBjQF1PPf9PTn+5tid8QJehZPndcoeD7J8fPJMAoGCCqG
+SM49BAMCA0kAMEYCIQDFUO0owvqMVRO2FmD+vb8mqJBpWCE6Cl5pEHaygTa5LwIh
+ANsmjI2azWiTSFjb7Ou5fnCfbeiJUP0s66m8qS4rYl9L
+ </ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="encryption">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/post" index="0" isDefault="true"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/redirect" index="1"/>
+ <md:AttributeConsumingService index="0" isDefault="true">
+ <md:ServiceName xml:lang="en">Default Service</md:ServiceName>
+ <md:RequestedAttribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="MANDATOR-LEGAL-PERSON-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.76" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="MANDATOR-LEGAL-PERSON-FULL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.84" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="MANDATE-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.68" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="MANDATOR-LEGAL-PERSON-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.100" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="urn:oid:1.2.40.0.10.2.1.1.261.34" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="MANDATE-TYPE-OID" Name="urn:oid:1.2.40.0.10.2.1.1.261.106" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="EID-IDENTITY-LINK" Name="urn:oid:1.2.40.0.10.2.1.1.261.38" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="EID-CITIZEN-QAA-EIDAS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.108" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ </md:AttributeConsumingService>
+ </md:SPSSODescriptor>
+ <md:Organization>
+ <md:OrganizationName xml:lang="de">EGIZ</md:OrganizationName>
+ <md:OrganizationDisplayName xml:lang="de">E-Government Innovationszentrum</md:OrganizationDisplayName>
+ <md:OrganizationURL xml:lang="de">http://www.egiz.gv.at</md:OrganizationURL>
+ </md:Organization>
+ <md:ContactPerson contactType="technical">
+ <md:Company>E-Government Innovationszentrum</md:Company>
+ <md:GivenName>Lenz</md:GivenName>
+ <md:SurName>Thomas</md:SurName>
+ <md:EmailAddress>thomas.lenz@egiz.gv.at</md:EmailAddress>
+ <md:TelephoneNumber>+43 316 873 5525</md:TelephoneNumber>
+ </md:ContactPerson>
+</md:EntityDescriptor>
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
new file mode 100644
index 00000000..99552053
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
+
+ <bean id="dummyAuthConfig"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig" />
+
+ <bean id="dummyVelocityGuiBuilder"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyVelocityGuiFormBuilder" />
+
+ <bean id="dummyGuiBuilderConfigFactory"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory" />
+
+ <bean id="httpClientFactory"
+ class="at.gv.egiz.eaaf.core.impl.utils.HttpClientFactory" />
+
+ <bean id="dummyRevisionLogger"
+ class="at.gv.egiz.eaaf.core.impl.logging.DummyRevisionsLogger" />
+
+ <bean id="eaafKeyStoreFactory"
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+
+</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml
new file mode 100644
index 00000000..2bddd629
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
+
+ <import resource="test_eaaf_core.beans.xml"/>
+ <import resource="classpath:/eaaf_pvp.beans.xml"/>
+ <import resource="classpath:/eaaf_pvp_idp.beans.xml"/>
+
+ <bean id="dummyCredentialProvider"
+ class="at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider" />
+
+ <bean id="dummyChainingMetadataResolver"
+ class="at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider" />
+
+ <bean id="samlVerificationEngine"
+ class="at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine" />
+
+ <bean id="dummyLoALevelMapper"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyLoALevelMapper" />
+
+ <bean id="dummySubjectNameIdGenerator"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummySubjectNameGenerator" />
+
+ <bean id="dummyPvpBasicConfig"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpConfiguration" />
+
+ <bean id="dummyMetadataConfigFactor"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpMetadataConfigFactory" />
+
+ <bean id="PVPAuthenticationRequestAction"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.AuthenticationAction">
+ <property name="pvpIdpCredentials" ref="dummyCredentialProvider" />
+ </bean>
+
+ <bean id="pvpMetadataService"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.MetadataAction" >
+ <property name="pvpIdpCredentials" ref="dummyCredentialProvider" />
+ </bean>
+
+</beans> \ No newline at end of file