aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2022-08-17 10:51:54 +0000
committerThomas Lenz <thomas.lenz@egiz.gv.at>2022-08-17 10:51:54 +0000
commitd83cf36c1454a10f5a46d677b5f0f30e0cbe7e95 (patch)
tree1cf2bf2853d604d8579cc3f5bf411d10f80c0207 /modules
parent48f19dc45cec670fe62399d09fb34732fb4eeedc (diff)
parent920d33465e5ab1a71d81cc280e41de10cd8b5247 (diff)
downloadNational_eIDAS_Gateway-d83cf36c1454a10f5a46d677b5f0f30e0cbe7e95.tar.gz
National_eIDAS_Gateway-d83cf36c1454a10f5a46d677b5f0f30e0cbe7e95.tar.bz2
National_eIDAS_Gateway-d83cf36c1454a10f5a46d677b5f0f30e0cbe7e95.zip
Merge branch 'feature/ms_proxy_service' into 'nightlybuild'
add basic implementation of eIDAS-Node Proxy-Service request-controller See merge request egiz/eidas_at_proxy!20
Diffstat (limited to 'modules')
-rw-r--r--modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml8
-rw-r--r--modules/authmodule-eIDAS-v2/pom.xml13
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0-sources.jarbin0 -> 203436 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.jarbin0 -> 300354 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.pom114
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0-sources.jarbin0 -> 4156 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.jarbin0 -> 6234 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.pom61
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0-sources.jarbin0 -> 2850 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.jarbin0 -> 3853 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.pom94
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0-sources.jarbin0 -> 90806 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.jarbin0 -> 126073 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.pom59
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-parent/2.6.0/eidas-parent-2.6.0.pom900
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0-sources.jarbin0 -> 49656 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.jarbin0 -> 59363 bytes
-rw-r--r--modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.pom125
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java82
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java2
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java23
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java23
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java99
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java8
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeSpecificDetailSearchProcessor.java5
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java8
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ConnectorEidasAttributeRegistry.java107
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java180
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java1
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java39
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java1
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseAlternativeTask.java5
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java8
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java43
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/validator/EidasResponseValidator.java24
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml16
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasSignalServletTest.java9
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java8
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java8
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java15
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java19
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java11
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java7
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java15
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java15
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAuthnResponseTaskTest.java17
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveEidasResponseTaskTest.java19
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java15
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java46
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasResponseValidatorTest.java8
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml14
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_tasks_test.xml14
-rw-r--r--modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties6
-rw-r--r--modules/authmodule_id-austria/checks/spotbugs-exclude.xml29
-rw-r--r--modules/authmodule_id-austria/pom.xml150
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java123
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthenticationSpringResourceProvider.java56
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaEidasProxyAuthenticationModulImpl.java91
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/EidasConnecorUniqueIdAttributeBuilder.java52
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/SpRequiredAttributersAttributeBuilder.java63
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMessageSource.java22
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMetadataConfiguration.java462
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthRequestBuilderConfiguration.java307
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthMetadataController.java150
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthSignalController.java94
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java370
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java211
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthCredentialProvider.java130
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthMetadataProvider.java168
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/Utils.java44
-rw-r--r--modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider1
-rw-r--r--modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder2
-rw-r--r--modules/authmodule_id-austria/src/main/resources/messages/idaustria_auth_messages.properties10
-rw-r--r--modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml18
-rw-r--r--modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml36
-rw-r--r--modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml23
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaAuthSpringResourceProviderTest.java56
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaEidasProxyAuthenticationModulImplTest.java102
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/EidasConnecorUniqueIdAttributeBuilderTest.java54
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/SpRequiredAttributersAttributeBuilderTest.java72
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/config/IdAustriaAuthMessageSourceTest.java50
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java186
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthSignalControllerTest.java200
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java790
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java478
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthCredentialProviderTest.java413
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java236
-rw-r--r--modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderSecondTest.java65
-rw-r--r--modules/authmodule_id-austria/src/test/resources/config/junit.jksbin0 -> 3980 bytes
-rw-r--r--modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties44
-rw-r--r--modules/authmodule_id-austria/src/test/resources/config/junit_test.jksbin0 -> 8410 bytes
-rw-r--r--modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jksbin0 -> 4818 bytes
-rw-r--r--modules/authmodule_id-austria/src/test/resources/config/pvp.jksbin0 -> 4833 bytes
-rw-r--r--modules/authmodule_id-austria/src/test/resources/config/pvp.p12bin0 -> 5494 bytes
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID.xml49
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_bpk_without_prefix.xml49
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_minimum.xml43
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_eid_sector_attr.xml52
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml63
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml66
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_wrong_data.xml46
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_with_wrong_destination_endpoint.xml52
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_classpath_entityid.xml52
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error.xml46
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_empty_subcode.xml46
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_userstop.xml46
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_without_subcode.xml45
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/eidas_node_siging.crt21
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/idp_metadata_classpath_entity.xml146
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig.xml46
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig2.xml46
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_notvalid.xml84
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_valid_wrong_alg.xml74
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/junit_keystore_metadata.crt11
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/junit_keystore_signing.crt18
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/moa_sig_signing.crt27
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/pvp_postbinding_template.html3
-rw-r--r--modules/authmodule_id-austria/src/test/resources/data/sp_metadata_junit.xml66
-rw-r--r--modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml20
-rw-r--r--modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml32
-rw-r--r--modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_lazy.xml24
-rw-r--r--modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/MsEidasNodeConstants.java13
-rw-r--r--modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/config/ServiceProviderConfiguration.java19
-rw-r--r--modules/core_common_lib/src/test/java/at/asitplus/eidas/specific/core/test/config/dummy/MsConnectorDummyConfigMap.java8
-rw-r--r--modules/core_common_webapp/pom.xml27
-rw-r--r--modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java187
-rw-r--r--modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java10
-rw-r--r--modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java2
-rw-r--r--modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml3
-rw-r--r--modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java311
-rw-r--r--modules/core_commons_eidas/checks/spotbugs-exclude.xml9
-rw-r--r--modules/core_commons_eidas/pom.xml174
-rw-r--r--modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/EidasConstants.java85
-rw-r--r--modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/service/EidasAttributeRegistry.java97
-rw-r--r--modules/core_commons_eidas/src/main/resources/eidas_v2_auth_ref_impl_config.beans.xml (renamed from modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth_ref_impl_config.beans.xml)0
-rw-r--r--modules/core_commons_eidas/src/test/java/at/asitplus/eidas/specific/modules/core/eidas/test/dummy/DummySpecificCommunicationService.java (renamed from modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummySpecificCommunicationService.java)10
-rw-r--r--modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml31
-rw-r--r--modules/eidas_proxy-sevice/pom.xml193
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java22
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java59
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java55
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java49
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java29
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java91
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java19
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java138
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java36
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java524
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java373
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java28
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java249
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java45
-rw-r--r--modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider1
-rw-r--r--modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties14
-rw-r--r--modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml41
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java50
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java56
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java197
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java852
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java982
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java162
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml68
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml376
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json215
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties19
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties18
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml20
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml20
-rw-r--r--modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml34
-rw-r--r--modules/pom.xml5
170 files changed, 14414 insertions, 537 deletions
diff --git a/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml b/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml
index 9b12a750..84efc85d 100644
--- a/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml
+++ b/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml
@@ -23,13 +23,7 @@
<Class name="at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasSignalServlet" />
<Method name="restoreEidasAuthProcess" />
<Bug pattern="SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING" />
- </Match>
- <Match>
- <!-- File path is only loaded from configuration -->
- <Class name="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry" />
- <Method name="initialize" />
- <Bug pattern="PATH_TRAVERSAL_IN" />
- </Match>
+ </Match>
<Match>
<!-- Redirect URL is only loaded from configuration -->
<Class name="at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.GenerateAuthnRequestTask" />
diff --git a/modules/authmodule-eIDAS-v2/pom.xml b/modules/authmodule-eIDAS-v2/pom.xml
index 4fe775cc..1ac03fbb 100644
--- a/modules/authmodule-eIDAS-v2/pom.xml
+++ b/modules/authmodule-eIDAS-v2/pom.xml
@@ -30,7 +30,7 @@
<repository>
<id>eIDASNode-local</id>
<name>local</name>
- <url>file:${basedir}/repository</url>
+ <url>file:${basedir}/../../repository</url>
</repository>
</repositories>
</profile>
@@ -46,6 +46,10 @@
<artifactId>core_common_lib</artifactId>
</dependency>
<dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_commons_eidas</artifactId>
+ </dependency>
+ <dependency>
<groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf-core</artifactId>
</dependency>
@@ -194,7 +198,12 @@
<scope>test</scope>
<type>test-jar</type>
</dependency>
-
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_commons_eidas</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf_core_utils</artifactId>
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0-sources.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0-sources.jar
new file mode 100644
index 00000000..9313fbe2
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0-sources.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.jar
new file mode 100644
index 00000000..489a118d
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.pom b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.pom
new file mode 100644
index 00000000..b254385d
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-commons/2.6.0/eidas-commons-2.6.0.pom
@@ -0,0 +1,114 @@
+<!--
+ ~ Copyright (c) 2021 by European Commission
+ ~
+ ~ 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/page/eupl-text-11-12
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the Licence is distributed on an "AS IS" basis,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ ~ implied.
+ ~ See the Licence for the specific language governing permissions and
+ ~ limitations under the Licence.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>eidas-commons</artifactId>
+ <packaging>${mod.packaging.type}</packaging>
+ <name>eIDAS Commons</name>
+ <description>
+ The EIDASCommons library provides beans, Java Interfaces and utility classes to integrate EidasNode and SAML
+ Engine.
+ </description>
+ <parent>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-parent</artifactId>
+ <version>2.6.0</version>
+ <relativePath>../EIDAS-Parent/pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-light-commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.owasp.encoder</groupId>
+ <artifactId>encoder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.cache</groupId>
+ <artifactId>cache-api</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ <!-- TEST -->
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>aopalliance</groupId>
+ <artifactId>aopalliance</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <includes>
+ <include>log4j.xml</include>
+ <include>*.properties</include>
+ </includes>
+ </testResource>
+ </testResources>
+ </build>
+ <profiles>
+ <profile>
+ <id>metrics</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0-sources.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0-sources.jar
new file mode 100644
index 00000000..76de9f21
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0-sources.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.jar
new file mode 100644
index 00000000..f47d9387
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.pom b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.pom
new file mode 100644
index 00000000..00c9b834
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite-specific-communication/2.6.0/eidas-jcache-ignite-specific-communication-2.6.0.pom
@@ -0,0 +1,61 @@
+<!--
+ ~ Copyright (c) 2020 by European Commission
+ ~
+ ~ 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/page/eupl-text-11-12
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the Licence is distributed on an "AS IS" basis,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ ~ implied.
+ ~ See the Licence for the specific language governing permissions and
+ ~ limitations under the Licence
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>eidas-jcache-ignite-specific-communication</artifactId>
+ <packaging>jar</packaging>
+ <name>eIDAS JCache Ignite Specific Communication</name>
+ <description>Implements JCache using Ignite with Specific Communication Definition's beans configurations.</description>
+
+ <parent>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-parent</artifactId>
+ <version>2.6.0</version>
+ <relativePath>../EIDAS-Parent/pom.xml</relativePath>
+ </parent>
+
+ <properties>
+ <ignite.version>2.8.1</ignite.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-slf4j</artifactId>
+ <version>${ignite.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0-sources.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0-sources.jar
new file mode 100644
index 00000000..f30cd314
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0-sources.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.jar
new file mode 100644
index 00000000..10487964
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.pom b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.pom
new file mode 100644
index 00000000..adc838fa
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-jcache-ignite/2.6.0/eidas-jcache-ignite-2.6.0.pom
@@ -0,0 +1,94 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>eidas-jcache-ignite</artifactId>
+ <packaging>jar</packaging>
+ <name>eIDAS JCache Ignite</name>
+ <description>Implements JCache using Ignite.</description>
+
+ <parent>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-parent</artifactId>
+ <version>2.6.0</version>
+ <relativePath>../EIDAS-Parent/pom.xml</relativePath>
+ </parent>
+
+ <properties>
+ <ignite.version>2.8.1</ignite.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${ignite.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.gridgain</groupId>
+ <artifactId>ignite-shmem</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-spring</artifactId>
+ <version>${ignite.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-indexing</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-expression</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-slf4j</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0-sources.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0-sources.jar
new file mode 100644
index 00000000..34de1733
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0-sources.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.jar
new file mode 100644
index 00000000..a24f36cd
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.pom b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.pom
new file mode 100644
index 00000000..1a9eccef
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-light-commons/2.6.0/eidas-light-commons-2.6.0.pom
@@ -0,0 +1,59 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>eidas-light-commons</artifactId>
+ <packaging>${mod.packaging.type}</packaging>
+ <name>eIDAS Light Commons</name>
+ <description>
+ The EIDASLightCommons library provides Java Interfaces and utility classes to integrate EIDASCommons and eIDAS Specific Communication Definition.
+ </description>
+ <parent>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-parent</artifactId>
+ <version>2.6.0</version>
+ <relativePath>../EIDAS-Parent/pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>jakarta.xml.bind</groupId>
+ <artifactId>jakarta.xml.bind-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>icu4j</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>metrics</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-parent/2.6.0/eidas-parent-2.6.0.pom b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-parent/2.6.0/eidas-parent-2.6.0.pom
new file mode 100644
index 00000000..fe858c92
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-parent/2.6.0/eidas-parent-2.6.0.pom
@@ -0,0 +1,900 @@
+<!--
+ ~ Copyright (c) 2022 by European Commission
+ ~
+ ~ 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/page/eupl-text-11-12
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the Licence is distributed on an "AS IS" basis,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ ~ implied.
+ ~ See the Licence for the specific language governing permissions and
+ ~ limitations under the Licence.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-parent</artifactId>
+ <packaging>pom</packaging>
+ <name>eIDAS Node Parent</name>
+ <version>2.6.0</version>
+ <description>
+ The EIDAS-Parent provides artifacts versions for Eidas Node components.
+ </description>
+ <properties>
+ <!-- 1) Project properties -->
+ <proj.name>EIDASParent</proj.name>
+ <proj.name.eidas>EidasNode</proj.name.eidas>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <app.packaging.type>war</app.packaging.type>
+ <mod.packaging.type>jar</mod.packaging.type>
+ <timestamp>${maven.build.timestamp}</timestamp>
+ <!-- java version targeted in the compile phase -->
+ <java.version>11</java.version>
+
+ <samlspec.version>0.5.2</samlspec.version>
+ <samlspecacept.version>0.5.1</samlspecacept.version>
+
+ <!-- 2) Library dependency versions -->
+ <spring.version>4.3.18.RELEASE</spring.version>
+ <opensaml.not-yet-commons-ssl.version>0.3.9</opensaml.not-yet-commons-ssl.version>
+ <opensaml.openws.version>1.5.5</opensaml.openws.version>
+ <opensaml.version>4.1.1</opensaml.version>
+ <opensaml.api.version>4.1.1</opensaml.api.version>
+ <xmlsec.version>2.2.3</xmlsec.version>
+ <shibboleth.xmlsupport.version>8.0.0</shibboleth.xmlsupport.version>
+ <servlet.version>3.0.1</servlet.version>
+ <jaxb.api.version>2.3.3</jaxb.api.version>
+ <jaxb.runtime.version>2.3.3</jaxb.runtime.version>
+ <json.runtime.version>1.1.4</json.runtime.version>
+ <jsp.api>2.0</jsp.api>
+ <jstl.version>1.2.6</jstl.version>
+ <jasper.version>6.0.53</jasper.version>
+ <slf4j.version>1.7.10</slf4j.version>
+ <logback.version>1.2.9</logback.version>
+ <mockito.version>3.7.0</mockito.version>
+ <junit.version>4.12</junit.version>
+ <hamcrest.version>1.3</hamcrest.version>
+ <commons.codec>1.15</commons.codec>
+ <commons.collections>3.2.2</commons.collections>
+ <commons.io>2.4</commons.io>
+ <commons.lang>2.6</commons.lang>
+ <commons.logging>1.1.3</commons.logging>
+ <commons.httpclient>4.5.13</commons.httpclient>
+ <commons.httpcore>4.4.9</commons.httpcore>
+ <commons.lang3>3.1</commons.lang3>
+ <bouncycastle.version>1.70</bouncycastle.version>
+ <owasp.version>1.2.3</owasp.version>
+ <owasp.dependency-check.version>1.4.0</owasp.dependency-check.version>
+ <joda.time.version>2.6</joda.time.version>
+ <log4j.version>1.2.17</log4j.version>
+ <log4j.api>2.3</log4j.api>
+ <xmlunit.version>1.5</xmlunit.version>
+ <bdr.econnector.version>1.2.2</bdr.econnector.version>
+ <struts.version>2.3.34</struts.version>
+ <vaadin.version>7.4.2</vaadin.version>
+ <vaadin.plugin.version>${vaadin.version}</vaadin.plugin.version>
+ <vaadin-spring.version>1.0.0.beta1</vaadin-spring.version>
+ <vaadin4spring.version>0.0.5.RELEASE</vaadin4spring.version>
+ <jetty.plugin.version>9.2.3.v20140905</jetty.plugin.version>
+ <guava.version>28.1-jre</guava.version>
+ <jsr305.version>3.0.1</jsr305.version>
+ <icu4j.version>57.1</icu4j.version>
+
+ <!-- 3) maven plugin versions -->
+ <javadoc.plugin.version>2.8.1</javadoc.plugin.version>
+ <compile.plugin.version>3.8.0</compile.plugin.version>
+ <surefire.plugin.version>2.19.1</surefire.plugin.version>
+ <war.plugin.version>3.2.0</war.plugin.version>
+ <ear.plugin.version>2.7</ear.plugin.version>
+ <resources.plugin.version>2.4</resources.plugin.version>
+ <jacoco.plugin.version>0.8.7</jacoco.plugin.version>
+ <remote.resources.plugin.version>1.5</remote.resources.plugin.version>
+ <source.plugin.version>2.1.2</source.plugin.version>
+ <install.plugin.version>2.5.2</install.plugin.version>
+ <clean.plugin.version>2.6.1</clean.plugin.version>
+ <maven.jar.plugin.version>3.1.2</maven.jar.plugin.version>
+ <jaxb.plugin.version>2.5.0</jaxb.plugin.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- eIDAS modules -->
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>SimpleProtocol</artifactId>
+ <version>0.0.4-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-commons</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-light-commons</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-encryption</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-saml-engine</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-updater</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-saml-metadata</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-specific-connector</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-specific-proxyservice</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-specific-communication-definition</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-dev</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-dev-node</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-dev-specific-communication</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite-node</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite-specific-communication</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-node</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-sp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-idp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- Servlets -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>${servlet.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.web</groupId>
+ <artifactId>jakarta.servlet.jsp.jstl</artifactId>
+ <version>${jstl.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <!-- JSP Java Server Pages -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jsp-api</artifactId>
+ <version>${jsp.api}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>jasper-el</artifactId>
+ <version>${jasper.version}</version>
+ </dependency>
+
+ <!-- Struts2 -->
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <version>${struts.version}</version>
+ </dependency>
+
+ <!-- Spring -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${spring.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+
+ <!-- XML -->
+ <!-- JAXB Jakarta XML Binding -->
+ <dependency>
+ <groupId>jakarta.xml.bind</groupId>
+ <artifactId>jakarta.xml.bind-api</artifactId>
+ <version>${jaxb.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jaxb</groupId>
+ <artifactId>jaxb-runtime</artifactId>
+ <version>${jaxb.runtime.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <version>${json.runtime.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>xalan</groupId>
+ <artifactId>xalan</artifactId>
+ <version>${xalan.version}</version>
+ </dependency>
+ <!-- OpenSaml -->
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-core</artifactId>
+ <version>${opensaml.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-saml-api</artifactId>
+ <version>${opensaml.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-saml-impl</artifactId>
+ <version>${opensaml.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-security-api</artifactId>
+ <version>${opensaml.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-security-impl</artifactId>
+ <version>${opensaml.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.shibboleth.utilities</groupId>
+ <artifactId>java-support</artifactId>
+ <version>${shibboleth.xmlsupport.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-xmlsec-api</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </exclusion>
+ </exclusions>
+ <version>${opensaml.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-xmlsec-impl</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </exclusion>
+ </exclusions>
+ <version>${opensaml.version}</version>
+ </dependency>
+ <dependency>
+ <!-- EIDINT-4171: Security upgrade of org.apache.santuario:xmlsec found in opensaml-xmlsec-impl -->
+ <groupId>org.apache.santuario</groupId>
+ <artifactId>xmlsec</artifactId>
+ <version>${xmlsec.version}</version>
+ </dependency>
+
+ <!--Logging-->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>${commons.logging}</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>${log4j.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jdmk</groupId>
+ <artifactId>jmxtools</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jmx</groupId>
+ <artifactId>jmxri</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>mail</artifactId>
+ <groupId>javax.mail</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${logback.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Apache Commons -->
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>${commons.codec}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>${commons.collections}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>${commons.httpclient}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>${commons.httpcore}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>${commons.io}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>${commons.lang}</version>
+ </dependency>
+
+ <!-- Additional Dependencies -->
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <version>${joda.time.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.owasp.encoder</groupId>
+ <artifactId>encoder</artifactId>
+ <version>${owasp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.owasp.encoder</groupId>
+ <artifactId>encoder-jsp</artifactId>
+ <version>${owasp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <version>${jsr305.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Bouncy Castle -->
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ <version>${bouncycastle.version}</version>
+ </dependency>
+
+ <!-- International Components for Unicode and Transliteration -->
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>icu4j</artifactId>
+ <version>${icu4j.version}</version>
+ </dependency>
+
+ <!-- UNIT TEST Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <version>${hamcrest.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>${xmlunit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <version>${spring.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!-- Dependencies in common for all modules -->
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </dependency>
+
+ <!-- UNIT TEST Dependencies in common for all modules -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <exclusions>
+ <exclusion>
+ <artifactId>hamcrest-core</artifactId>
+ <groupId>org.hamcrest</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <exclusions>
+ <exclusion>
+ <artifactId>hamcrest-core</artifactId>
+ <groupId>org.hamcrest</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+
+ <plugin>
+ <groupId>com.orctom.mojo</groupId>
+ <artifactId>was-maven-plugin</artifactId>
+ <version>1.0.8</version>
+ <configuration>
+ <wasHome>c:/pgm/wlp</wasHome>
+ <applicationName>${proj.name}</applicationName>
+ <host>localhost</host>
+ <server>server01</server>
+ <node>node01</node>
+ <virtualHost>default_host</virtualHost>
+ <verbose>true</verbose>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.tomcat.maven</groupId>
+ <artifactId>tomcat7-maven-plugin</artifactId>
+ <version>2.2</version>
+ <configuration>
+ <url>http://localhost:8080/manager/text</url>
+ <server>tomcat</server>
+ <path>/${proj.name}</path>
+ <username>admin</username>
+ <password>admin</password>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>${war.plugin.version}</version>
+ <configuration>
+ <webResources>
+ <resource>
+ <directory>${project.basedir}/src/main/webapp/WEB-INF</directory>
+ <filtering>true</filtering>
+ <targetPath>WEB-INF</targetPath>
+ <includes>
+ <include>**/web.xml</include>
+ </includes>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${source.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <version>${jacoco.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>default-prepare-agent</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>default-report</id>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ <configuration>
+ <formats>HTML,XML</formats>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jaxb2-maven-plugin</artifactId>
+ <version>${jaxb.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>${resources.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>${maven.jar.plugin.version}</version>
+ </plugin>
+ <!--plugin>
+ <groupId>org.owasp</groupId>
+ <artifactId>dependency-check-maven</artifactId>
+ <version>${owasp.dependency-check.version}</version>
+ <configuration>
+ <failBuildOnCVSS>8</failBuildOnCVSS>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin-->
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${compile.plugin.version}</version>
+ <configuration>
+ <source>${java.version}</source>
+ <target>${java.version}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.plugin.version}</version>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <configuration>
+ <detectLinks>true</detectLinks>
+ <additionalJOption>--add-exports java.base/sun.security.rsa=ALL-UNNAMED</additionalJOption>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <modules>
+ <module>../EIDAS-Light-Commons</module>
+ <module>../EIDAS-Commons</module>
+ <module>../EIDAS-Encryption</module>
+ <module>../EIDAS-Metadata</module>
+ <module>../EIDAS-SpecificCommunicationDefinition</module>
+ <!--start of TODO remove when/if EIDAS-Node pom does not depend on eidas-jcache-dev-node artifact to test-->
+ <module>../EIDAS-JCache-Dev</module>
+ <module>../EIDAS-JCache-Dev-Node</module>
+ <!--TODOEND-->
+ </modules>
+ <profiles>
+ <profile>
+ <id>NodeOnly</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>../EIDAS-SAMLEngine</module>
+ <module>../EIDAS-UPDATER</module>
+ <module>../EIDAS-Node</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>DemoToolsOnly</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <modules>
+ <module>../EIDAS-SimpleProtocol</module>
+ <module>../EIDAS-SpecificProxyService</module>
+ <module>../EIDAS-SpecificConnector</module>
+ <module>../EIDAS-SP</module>
+ <module>../EIDAS-IdP-1.0</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>nodeJcacheIgnite</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>../EIDAS-JCache-Ignite</module>
+ <module>../EIDAS-JCache-Ignite-Node</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>nodeJcacheDev</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>../EIDAS-JCache-Dev</module>
+ <module>../EIDAS-JCache-Dev-Node</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>specificCommunicationJcacheIgnite</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>../EIDAS-JCache-Ignite</module>
+ <module>../EIDAS-JCache-Ignite-Specific-Communication</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>specificCommunicationJcacheDev</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ <property>
+ <name>specificJar</name>
+ </property>
+ </activation>
+ <modules>
+ <module>../EIDAS-JCache-Dev</module>
+ <module>../EIDAS-JCache-Dev-Specific-Communication</module>
+ </modules>
+ </profile>
+ </profiles>
+</project>
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0-sources.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0-sources.jar
new file mode 100644
index 00000000..5e405828
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0-sources.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.jar b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.jar
new file mode 100644
index 00000000..f56a139e
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.jar
Binary files differ
diff --git a/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.pom b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.pom
new file mode 100644
index 00000000..df092575
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/repository/eu/eidas/eidas-specific-communication-definition/2.6.0/eidas-specific-communication-definition-2.6.0.pom
@@ -0,0 +1,125 @@
+<!--
+ ~ Copyright (c) 2022 by European Commission
+ ~
+ ~ 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/page/eupl-text-11-12
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the Licence is distributed on an "AS IS" basis,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ ~ implied.
+ ~ See the Licence for the specific language governing permissions and
+ ~ limitations under the Licence.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>eidas-specific-communication-definition</artifactId>
+ <packaging>jar</packaging>
+ <name>eIDAS Specific Communication Definition</name>
+ <description>Defines and implements the communication protocol to be used between specific and node modules.
+ </description>
+ <parent>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-parent</artifactId>
+ <version>2.6.0</version>
+ <relativePath>../EIDAS-Parent/pom.xml</relativePath>
+ </parent>
+ <properties>
+ <lightRequest.xsd>lightRequest.xsd</lightRequest.xsd>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jaxb</groupId>
+ <artifactId>jaxb-runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-dev</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jaxb2-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>xjc</id>
+ <goals>
+ <goal>xjc</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <sources>
+ <source>src/main/resources/xsds/${lightRequest.xsd}</source>
+ <source>src/main/resources/xsds/lightResponse.xsd</source>
+ </sources>
+ <packageName>eu.eidas.specificcommunication</packageName>
+ <noPackageLevelAnnotations>true</noPackageLevelAnnotations>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>specificCommunicationJcacheIgnite</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite-specific-communication</artifactId>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>specificCommunicationJcacheDev</id>
+ <!-- <activation> -->
+ <!-- <property> -->
+ <!-- <name>specificJar</name> -->
+ <!-- </property> -->
+ <!-- </activation> -->
+ <dependencies>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-dev-specific-communication</artifactId>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
index 66848fcc..3c41bf0a 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
@@ -23,6 +23,7 @@
package at.asitplus.eidas.specific.modules.auth.eidas.v2;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
public class Constants {
@@ -54,38 +55,36 @@ public class Constants {
*/
public static final String DATA_PERSON_MATCH_RESULT = "matching_result";
- // templates for post-binding forwarding
- public static final String TEMPLATE_POST_FORWARD_NAME = "eidas_node_forward.html";
- public static final String TEMPLATE_POST_FORWARD_ENDPOINT = "endPoint";
- public static final String TEMPLATE_POST_FORWARD_TOKEN_NAME = "tokenName";
- public static final String TEMPLATE_POST_FORWARD_TOKEN_VALUE = "tokenValue";
+
// configuration properties
- public static final String CONIG_PROPS_EIDAS_PREFIX = "auth.eIDAS";
-
+
public static final String CONIG_PROPS_EIDAS_WORKAROUND_STAGING_MS_CONNECTOR =
- CONIG_PROPS_EIDAS_PREFIX + ".workarounds.staging.msconnector.endpoint";
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".workarounds.staging.msconnector.endpoint";
public static final String CONIG_PROPS_EIDAS_IS_TEST_IDENTITY =
- CONIG_PROPS_EIDAS_PREFIX + ".eid.testidentity.default";
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".eid.testidentity.default";
- public static final String CONIG_PROPS_EIDAS_NODE = CONIG_PROPS_EIDAS_PREFIX + ".node_v2";
+ public static final String CONIG_PROPS_EIDAS_NODE = EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".node_v2";
public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode";
public static final String CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS = CONIG_PROPS_EIDAS_NODE
+ ".publicSectorTargets";
public static final String CONIG_PROPS_EIDAS_NODE_ENTITYID = CONIG_PROPS_EIDAS_NODE + ".entityId";
- public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_URL = CONIG_PROPS_EIDAS_NODE
+ public static final String CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL = CONIG_PROPS_EIDAS_NODE
+ ".forward.endpoint";
+
public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD = CONIG_PROPS_EIDAS_NODE
+ ".forward.method";
+
public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL =
- CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural";
+ EidasConstants.CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural";
public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL =
- CONIG_PROPS_EIDAS_NODE + ".attributes.requested.{0}.onlynatural";
+ EidasConstants.CONIG_PROPS_EIDAS_NODE + ".attributes.requested.{0}.onlynatural";
public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_REPRESENTATION =
- CONIG_PROPS_EIDAS_NODE + ".attributes.requested.representation";
+ EidasConstants.CONIG_PROPS_EIDAS_NODE + ".attributes.requested.representation";
+
public static final String CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION =
- CONIG_PROPS_EIDAS_NODE + ".requesterId.useHashedForm";
+ EidasConstants.CONIG_PROPS_EIDAS_NODE + ".requesterId.useHashedForm";
public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_REQUESTERID_FOR_LUX =
CONIG_PROPS_EIDAS_NODE + ".requesterId.lu.useStaticRequesterForAll";
@@ -106,7 +105,8 @@ public class Constants {
// Common SSL client configuration
- public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT = CONIG_PROPS_EIDAS_PREFIX + ".client.common";
+ public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".client.common";
public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_COMMON_CLIENT
+ ".ssl.keyStore.path";
public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_PASSWORD = CONIG_PROPS_EIDAS_COMMON_CLIENT
@@ -129,15 +129,17 @@ public class Constants {
+ ".ssl.trustStore.name";
/** Enable / Disable matching based on address search. **/
- public static final String CONFIG_PROP_MATCHING_BY_ADDRESS = CONIG_PROPS_EIDAS_PREFIX + ".matching.byaddress.enable";
+ public static final String CONFIG_PROP_MATCHING_BY_ADDRESS =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".matching.byaddress.enable";
public static final String CONFIG_PROP_MATCHING_BY_ADDRESS_MAX_RESULTS =
- CONIG_PROPS_EIDAS_PREFIX + ".matching.byaddress.maxresults";
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".matching.byaddress.maxresults";
public static final String DEFAULT_MATCHING_BY_ADDRESS_MAX_RESULTS = "250";
// ZMR Client configuration properties
- public static final String CONIG_PROPS_EIDAS_ZMRCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".zmrclient";
+ public static final String CONIG_PROPS_EIDAS_ZMRCLIENT =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".zmrclient";
public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_ENDPOINT = CONIG_PROPS_EIDAS_ZMRCLIENT
+ ".endpoint";
public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_DEBUG_TRACEMESSAGES = CONIG_PROPS_EIDAS_ZMRCLIENT
@@ -174,7 +176,8 @@ public class Constants {
+ ".ssl.trustStore.name";
// ErnP Client configuration properties
- public static final String CONIG_PROPS_EIDAS_ERNPCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".ernpclient";
+ public static final String CONIG_PROPS_EIDAS_ERNPCLIENT =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".ernpclient";
public static final String CONIG_PROPS_EIDAS_ERNPCLIENT_ENDPOINT = CONIG_PROPS_EIDAS_ERNPCLIENT
+ ".endpoint";
public static final String CONIG_PROPS_EIDAS_ERNPCLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_ERNPCLIENT
@@ -209,7 +212,8 @@ public class Constants {
// SZR Client configuration properties
- public static final String CONIG_PROPS_EIDAS_SZRCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".szrclient";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".szrclient";
public static final String CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE = CONIG_PROPS_EIDAS_SZRCLIENT
+ ".useTestService";
public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES = CONIG_PROPS_EIDAS_SZRCLIENT
@@ -267,7 +271,7 @@ public class Constants {
public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_REVISIONLOGDATASTORE_ACTIVE =
CONIG_PROPS_EIDAS_SZRCLIENT + ".revisionlog.eidmapping.active";
- public static final String DEFAULT_MS_NODE_COUNTRY_CODE = "AT";
+
@Deprecated
public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_SQLLITEDATASTORE_URL =
@@ -285,46 +289,12 @@ public class Constants {
// eIDAS request parameters
public static final String eIDAS_REQ_NAMEID_FORMAT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent";
- // eIDAS attribute names
- public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier";
- public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth";
- public static final String eIDAS_ATTR_CURRENTGIVENNAME = "FirstName";
- public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName";
- public static final String eIDAS_ATTR_PLACEOFBIRTH = "PlaceOfBirth";
- public static final String eIDAS_ATTR_BIRTHNAME = "BirthName";
- public static final String eIDAS_ATTR_CURRENTADDRESS = "CurrentAddress";
- public static final String eIDAS_ATTR_TAXREFERENCE = "TaxReference";
-
- public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier";
- public static final String eIDAS_ATTR_LEGALNAME = "LegalName";
-
-
- //eIDAS attribute URN
- public static final String eIDAS_ATTRURN_PREFIX = "http://eidas.europa.eu/attributes/";
- public static final String eIDAS_ATTRURN_PREFIX_NATURAL = eIDAS_ATTRURN_PREFIX + "naturalperson/";
-
- public static final String eIDAS_ATTRURN_PERSONALIDENTIFIER =
- eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PERSONALIDENTIFIER;
- public static final String eIDAS_ATTRURN_CURRENTGIVENNAME =
- eIDAS_ATTRURN_PREFIX_NATURAL + "CurrentGivenName";
- public static final String eIDAS_ATTRURN_CURRENTFAMILYNAME =
- eIDAS_ATTRURN_PREFIX_NATURAL + "CurrentFamilyName";
- public static final String eIDAS_ATTRURN_DATEOFBIRTH =
- eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_DATEOFBIRTH;
- public static final String eIDAS_ATTRURN_PLACEOFBIRTH =
- eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PLACEOFBIRTH;
- public static final String eIDAS_ATTRURN_BIRTHNAME =
- eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_BIRTHNAME;
-
-
public static final String eIDAS_REQ_PARAM_SECTOR_PUBLIC = "public";
public static final String eIDAS_REQ_PARAM_SECTOR_PRIVATE = "private";
public static final String POLICY_DEFAULT_ALLOWED_TARGETS =
EaafConstants.URN_PREFIX_CDID.replaceAll("\\.", "\\\\.").replaceAll("\\+", "\\\\+") + ".*";
- // SAML2 Constants
- public static final String SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success";
public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION = "30"; // seconds
public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE = "60"; // seconds
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java
index d3cac80c..e3600329 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java
@@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import com.google.common.collect.ImmutableSortedSet;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractProcessEngineSignalController;
import eu.eidas.auth.commons.EidasParameterKeys;
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 119a7c60..a847a519 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -65,6 +65,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenti
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ErnpRestCommunicationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.VersionHolder;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.base._20040201_.ServiceFault;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.EidasSuchdatenType;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest;
@@ -104,7 +105,7 @@ public class ErnpRestClient implements IErnpClient {
// "ERnP anwser for transaction: {0} with code: {1} and message: {2}";
private static final String PROCESS_SEARCH_PERSONAL_IDENTIFIER =
- "Searching " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER;
+ "Searching " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER;
private static final String PROCESS_SEARCH_MDS_ONLY = "Searching with MDS only";
private static final String PROCESS_SEARCH_COUNTRY_SPECIFIC = "Searching {0} specific";
@@ -139,7 +140,7 @@ public class ErnpRestClient implements IErnpClient {
// build search request
final SuchEidas eidasInfos = new SuchEidas();
- eidasInfos.setArt(Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER);
+ eidasInfos.setArt(EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER);
eidasInfos.setWert(personIdentifier);
eidasInfos.setStaatscode2(citizenCountryCode);
@@ -427,15 +428,15 @@ public class ErnpRestClient implements IErnpClient {
// build result
return RegisterResult.builder()
.pseudonym(selectAllEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER))
+ EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER))
.familyName(person.getPersonendaten().getFamilienname())
.givenName(person.getPersonendaten().getVorname())
.dateOfBirth(getTextualBirthday(person.getPersonendaten().getGeburtsdatum()))
.bpk(person.getPersonendaten().getBpkZp())
.placeOfBirth(selectSingleEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH))
+ EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH))
.birthName(selectSingleEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_BIRTHNAME))
+ EidasConstants.eIDAS_ATTRURN_BIRTHNAME))
.build();
}
@@ -501,11 +502,11 @@ public class ErnpRestClient implements IErnpClient {
//TODO: maybe we should re-factor SimpleEidasData to a generic data-model to facilitate arbitrary eIDAS attributes
Set<Eidas> result = new HashSet<>();
addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
+ EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
+ EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
+ EidasConstants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
return result;
@@ -596,17 +597,17 @@ public class ErnpRestClient implements IErnpClient {
private void buildNewEidasDocumens(PersonAnlegen ernpReq, SimpleEidasData eidData) {
ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym()));
+ EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym()));
if (StringUtils.isNotEmpty(eidData.getPlaceOfBirth())) {
ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
+ EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
}
if (StringUtils.isNotEmpty(eidData.getBirthName())) {
ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName()));
+ EidasConstants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName()));
}
}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java
index 8dbd0632..904afc37 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java
@@ -31,6 +31,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenti
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ZmrCommunicationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.VersionHolder;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.base._20040201.ClientInfoType;
import at.gv.bmi.namespace.zmr_su.base._20040201.Organisation;
import at.gv.bmi.namespace.zmr_su.base._20040201.RequestType;
@@ -95,7 +96,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
private static final String PROCESS_TASK_UPDATE = "ZPR_VO_Person_aendern";
private static final String PROCESS_SEARCH_PERSONAL_IDENTIFIER =
- "Searching " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER;
+ "Searching " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER;
private static final String PROCESS_SEARCH_MDS_ONLY = "Searching with MDS only";
private static final String PROCESS_SEARCH_COUNTRY_SPECIFIC = "Searching {0} specific";
private static final String PROCESS_SEARCH_BY_RESIDENCE = "Searching by residence";
@@ -133,7 +134,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
req.setPersonSuchenRequest(searchPersonReq);
final EidasSuchdatenType eidasInfos = new EidasSuchdatenType();
searchPersonReq.getEidasSuchdaten().add(eidasInfos);
- eidasInfos.setEidasArt(Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER);
+ eidasInfos.setEidasArt(EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER);
eidasInfos.setEidasWert(personPseudonym);
eidasInfos.setStaatscode2(citizenCountryCode);
@@ -589,15 +590,15 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
// build result
return RegisterResult.builder()
.pseudonym(selectAllEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER))
+ EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER))
.familyName(person.getNatuerlichePerson().getPersonenName().getFamilienname())
.givenName(person.getNatuerlichePerson().getPersonenName().getVorname())
.dateOfBirth(person.getNatuerlichePerson().getGeburtsdatum())
.bpk(extractBpkZp(person.getNatuerlichePerson()))
.placeOfBirth(selectSingleEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH))
+ EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH))
.birthName(selectSingleEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_BIRTHNAME))
+ EidasConstants.eIDAS_ATTRURN_BIRTHNAME))
.build();
}
@@ -765,19 +766,19 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
//TODO: maybe we should re-factor SimpleEidasData to a generic data-model to facilitate arbitrary eIDAS attributes
Set<EidasIdentitaetAnlageType> result = new HashSet<>();
addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
+ EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
+ EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
+ EidasConstants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
// add MDS attributes as 'eIDAS-Documents' too, because ZMR does not allow a MDS update on regular places.
addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_CURRENTGIVENNAME, eidData.getGivenName(), false);
+ EidasConstants.eIDAS_ATTRURN_CURRENTGIVENNAME, eidData.getGivenName(), false);
addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_CURRENTFAMILYNAME, eidData.getFamilyName(), false);
+ EidasConstants.eIDAS_ATTRURN_CURRENTFAMILYNAME, eidData.getFamilyName(), false);
addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_DATEOFBIRTH, eidData.getDateOfBirth(), false);
+ EidasConstants.eIDAS_ATTRURN_DATEOFBIRTH, eidData.getDateOfBirth(), false);
return result;
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
index 60138027..8716f80d 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
@@ -31,6 +31,7 @@ import static at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasRespon
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
import java.util.Base64;
import java.util.Map;
import java.util.regex.Matcher;
@@ -47,8 +48,9 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ConnectorEidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
@@ -64,7 +66,7 @@ import lombok.extern.slf4j.Slf4j;
public abstract class AbstractEidProcessor implements INationalEidProcessor {
@Autowired
- protected EidasAttributeRegistry attrRegistry;
+ protected ConnectorEidasAttributeRegistry attrRegistry;
@Autowired
protected IConfigurationWithSP basicConfig;
@@ -80,28 +82,31 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
@Override
public final SimpleEidasData postProcess(Map<String, Object> eidasAttrMap) throws EidPostProcessingException,
EidasAttributeException {
+
SimpleEidasData.SimpleEidasDataBuilder builder = SimpleEidasData.builder()
.personalIdentifier(EidasResponseUtils.processPersonalIdentifier(
- eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)))
+ eidasAttrMap.get(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)))
// MDS attributes
- .citizenCountryCode(processCountryCode(eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)))
- .pseudonym(processPseudonym(eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)))
- .familyName(processFamilyName(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)))
- .givenName(processGivenName(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME)))
- .dateOfBirth(processDateOfBirthToString(eidasAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH)))
+ .citizenCountryCode(processCountryCode(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)))
+ .pseudonym(processPseudonym(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)))
+ .familyName(processFamilyName(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)))
+ .givenName(processGivenName(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)))
+ .dateOfBirth(processDateOfBirthToString(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_DATEOFBIRTH)))
// additional attributes
- .placeOfBirth(processPlaceOfBirth(eidasAttrMap.get(Constants.eIDAS_ATTR_PLACEOFBIRTH)))
- .birthName(processBirthName(eidasAttrMap.get(Constants.eIDAS_ATTR_BIRTHNAME)))
- .address(processAddress(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS)));
+ .placeOfBirth(processPlaceOfBirth(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_PLACEOFBIRTH)))
+ .birthName(processBirthName(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_BIRTHNAME)))
+ .address(processAddress(eidasAttrMap.get(EidasConstants.eIDAS_ATTR_CURRENTADDRESS)));
- if (eidasAttrMap.containsKey(Constants.eIDAS_ATTR_TAXREFERENCE)) {
- builder.taxNumber(EidasResponseUtils.processTaxReference(eidasAttrMap.get(Constants.eIDAS_ATTR_TAXREFERENCE)));
+ if (eidasAttrMap.containsKey(EidasConstants.eIDAS_ATTR_TAXREFERENCE)) {
+ builder.taxNumber(EidasResponseUtils.processTaxReference(
+ eidasAttrMap.get(EidasConstants.eIDAS_ATTR_TAXREFERENCE)));
}
return builder.build();
+
}
@@ -124,6 +129,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected PostalAddressType processAddress(Object currentAddressObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processAddress(currentAddressObj);
+
}
/**
@@ -137,6 +143,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected String processBirthName(Object birthNameObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processBirthName(birthNameObj);
+
}
/**
@@ -150,6 +157,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected String processPlaceOfBirth(Object placeOfBirthObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processPlaceOfBirth(placeOfBirthObj);
+
}
/**
@@ -163,6 +171,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected DateTime processDateOfBirth(Object dateOfBirthObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processDateOfBirth(dateOfBirthObj);
+
}
/**
@@ -176,6 +185,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected String processGivenName(Object givenNameObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processGivenName(givenNameObj);
+
}
/**
@@ -189,6 +199,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected String processFamilyName(Object familyNameObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processFamilyName(familyNameObj);
+
}
/**
@@ -202,13 +213,14 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
protected String processPseudonym(Object personalIdObj) throws EidPostProcessingException,
EidasAttributeException {
return EidasResponseUtils.processPseudonym(personalIdObj);
+
}
/**
* Set ProviderName and RequestId into eIDAS AuthnRequest.
*
* @param pendingReq Current pendingRequest
- * @param authnRequestBuilder AuthnREquest builer
+ * @param authnRequestBuilder AuthnRequest builder
*/
protected void buildProviderNameAndRequesterIdAttribute(IRequest pendingReq, Builder authnRequestBuilder) {
final ISpConfiguration spConfig = pendingReq.getServiceProviderConfiguration();
@@ -258,6 +270,37 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
}
}
+ /**
+ * Build LoA based on Service-Provider configuration.
+ *
+ * @param spConfig Current SP configuration
+ * @param authnRequestBuilder AuthnRequest builder
+ */
+ protected void buildLevelOfAssurance(ISpConfiguration spConfig, Builder authnRequestBuilder) {
+ // TODO: set matching mode if eIDAS ref. impl. support this method
+
+ // TODO: update if eIDAS ref. impl. supports exact matching for non-notified LoA
+ // schemes
+ String loa = EaafConstants.EIDAS_LOA_HIGH;
+ if (spConfig.getRequiredLoA() != null) {
+ if (spConfig.getRequiredLoA().isEmpty()) {
+ log.info("No eIDAS LoA requested. Use LoA HIGH as default");
+ } else {
+ if (spConfig.getRequiredLoA().size() > 1) {
+ log.info(
+ "Currently only ONE requested LoA is supported for service provider. Use first one ... ");
+ }
+
+ loa = spConfig.getRequiredLoA().get(0);
+
+ }
+ }
+
+ log.debug("Request eIdAS node with LoA: " + loa);
+ authnRequestBuilder.levelsOfAssuranceValues(Arrays.asList(loa));
+
+ }
+
private String generateRequesterId(String requesterId) {
if (requesterId != null && basicConfig.getBasicConfigurationBoolean(
Constants.CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION, true)) {
@@ -302,7 +345,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
final ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder();
for (final Map.Entry<String, Boolean> attribute : requiredAttributes.entrySet()) {
final String name = attribute.getKey();
- final ImmutableSortedSet<AttributeDefinition<?>> byFriendlyName = attrRegistry
+ final ImmutableSortedSet<AttributeDefinition<?>> byFriendlyName = attrRegistry.getCoreRegistry()
.getCoreAttributeRegistry().getByFriendlyName(name);
if (!byFriendlyName.isEmpty()) {
final AttributeDefinition<?> attributeDefinition = byFriendlyName.first();
@@ -318,30 +361,4 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
}
- protected void buildLevelOfAssurance(ISpConfiguration spConfig, Builder authnRequestBuilder) {
-
- // TODO: set matching mode if eIDAS ref. impl. support this method
-
- // TODO: update if eIDAS ref. impl. supports exact matching for non-notified LoA
- // schemes
- String loa = EaafConstants.EIDAS_LOA_HIGH;
- if (spConfig.getRequiredLoA() != null) {
- if (spConfig.getRequiredLoA().isEmpty()) {
- log.info("No eIDAS LoA requested. Use LoA HIGH as default");
- } else {
- if (spConfig.getRequiredLoA().size() > 1) {
- log.info(
- "Currently only ONE requested LoA is supported for service provider. Use first one ... ");
- }
-
- loa = spConfig.getRequiredLoA().get(0);
-
- }
- }
-
- log.debug("Request eIdAS node with LoA: " + loa);
- authnRequestBuilder.levelOfAssurance(loa);
-
- }
-
}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java
index 6dc08181..2c1e8fdd 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java
@@ -32,10 +32,10 @@ import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.egiz.eaaf.core.impl.data.Triple;
@@ -70,15 +70,15 @@ public class DeEidProcessor extends AbstractEidProcessor {
protected String processPseudonym(Object uniqeIdentifierObj) throws EidPostProcessingException,
EidasAttributeException {
if (uniqeIdentifierObj == null || !(uniqeIdentifierObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
}
final Triple<String, String, String> eIdentifier =
EidasResponseUtils.parseEidasPersonalIdentifier((String) uniqeIdentifierObj);
- log.trace(getName() + " starts processing of attribute: " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ log.trace(getName() + " starts processing of attribute: " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
final String result = convertDeIdentifier(eIdentifier.getThird());
- log.debug(getName() + " finished processing of attribute: " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ log.debug(getName() + " finished processing of attribute: " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
return result;
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeSpecificDetailSearchProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeSpecificDetailSearchProcessor.java
index e05fe86b..64db9eed 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeSpecificDetailSearchProcessor.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeSpecificDetailSearchProcessor.java
@@ -27,6 +27,7 @@ import org.apache.commons.lang3.StringUtils;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.EidasSuchdatenType;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest;
import at.gv.e_government.reference.namespace.persondata.de._20040201.NatuerlichePersonTyp;
@@ -62,9 +63,9 @@ public class DeSpecificDetailSearchProcessor implements CountrySpecificDetailSea
//add addtional eIDAS attributes from DE
req.getEidasSuchdaten().add(buildEidasSuchData(
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
+ EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
req.getEidasSuchdaten().add(buildEidasSuchData(
- Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName()));
+ EidasConstants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName()));
return req;
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java
index b5493edb..bbfcb5ff 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java
@@ -32,7 +32,6 @@ import java.util.Map.Entry;
import javax.annotation.PostConstruct;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,11 +39,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.INationalEidProcessor;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.impl.data.Triple;
import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
@@ -107,9 +107,9 @@ public class CcSpecificEidProcessingService implements ICcSpecificEidProcessingS
public SimpleEidasData postProcess(Map<String, Object> eidasAttrMap) throws EidPostProcessingException,
EidasAttributeException {
// extract citizen country from eIDAS unique identifier
- final Object eIdentifierObj = eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ final Object eIdentifierObj = eidasAttrMap.get(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
if (eIdentifierObj == null || !(eIdentifierObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
}
final Triple<String, String, String> eIdentifier =
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ConnectorEidasAttributeRegistry.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ConnectorEidasAttributeRegistry.java
new file mode 100644
index 00000000..8a120093
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ConnectorEidasAttributeRegistry.java
@@ -0,0 +1,107 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.NonNull;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
+import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class ConnectorEidasAttributeRegistry {
+
+ @Autowired IConfigurationWithSP basicConfig;
+
+ @Getter
+ private EidasAttributeRegistry coreRegistry;
+
+ /**
+ * Attribute Registry for eIDAS Connector implementation.
+ * @param registry Core attribute registry
+ */
+ public ConnectorEidasAttributeRegistry(@Autowired EidasAttributeRegistry registry) {
+ this.coreRegistry = registry;
+
+ }
+
+
+ /**
+ * Get Map of attributes that are requested by default.
+ *
+ * @return Map of AttributeIdentifier, isRequired flag
+ */
+ @NonNull
+ public Map<String, Boolean> getDefaultAttributeSetFromConfiguration() {
+ /*
+ * TODO: select set for representation if mandates should be used. It's an open
+ * task in respect to requested eIDAS attributes and isRequired flag, because
+ * there can be a decision problem in case of natural or legal person
+ * representation! From an Austrian use-case point of view, an Austrian service
+ * provider can support mandates for natural and legal persons at the same time.
+ * However, we CAN NOT request attributes for natural AND legal persons on the
+ * same time, because it's not possible to represent both simultaneously.
+ */
+ final Map<String, String> configAttributes =
+ basicConfig.getBasicConfigurationWithPrefix(
+ Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL);
+ return processAttributeInfosFromConfig(configAttributes);
+
+ }
+
+ /**
+ * Get a Map of attributes that are additionally requested for a specific country.
+ *
+ * @param countryCode Country Code
+ * @return Map of AttributeIdentifier, isRequired flag
+ */
+ @NonNull
+ public Map<String, Boolean> getAttributeSetFromConfiguration(String countryCode) {
+
+ /*
+ * TODO: select set for representation if mandates should be used. It's an open
+ * task in respect to requested eIDAS attributes and isRequired flag, because
+ * there can be a decision problem in case of natural or legal person
+ * representation! From an Austrian use-case point of view, an Austrian service
+ * provider can support mandates for natural and legal persons at the same time.
+ * However, we CAN NOT request attributes for natural AND legal persons on the
+ * same time, because it's not possible to represent both simultaneously.
+ */
+ final Map<String, String> configAttributes =
+ basicConfig.getBasicConfigurationWithPrefix(
+ MessageFormat.format(
+ Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL,
+ countryCode.toLowerCase()));
+ return processAttributeInfosFromConfig(configAttributes);
+
+ }
+
+ private Map<String, Boolean> processAttributeInfosFromConfig(Map<String, String> configAttributes) {
+
+ final Map<String, Boolean> result = new HashMap<>();
+ for (final String el : configAttributes.values()) {
+ if (StringUtils.isNotEmpty(el.trim())) {
+ final List<String> attrDef = KeyValueUtils.getListOfCsvValues(el.trim());
+ boolean isRequired = false;
+ if (attrDef.size() == 2) {
+ isRequired = Boolean.parseBoolean(attrDef.get(1));
+ }
+
+ result.put(attrDef.get(0), isRequired);
+
+ }
+ }
+
+ log.trace("Load #" + result.size() + " requested attributes from configuration");
+ return result;
+
+ }
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java
deleted file mode 100644
index e73491ab..00000000
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2018 A-SIT Plus GmbH
- * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
- * A-SIT Plus GmbH, 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 "License");
- * You may not use this work except in compliance with the License.
- * You may obtain a copy of the License at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "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.asitplus.eidas.specific.modules.auth.eidas.v2.service;
-
-import java.io.File;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Service;
-
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
-import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
-import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
-import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
-import eu.eidas.auth.commons.attribute.AttributeRegistries;
-import eu.eidas.auth.commons.attribute.AttributeRegistry;
-
-@Service("attributeRegistry")
-public class EidasAttributeRegistry {
- private static final Logger log = LoggerFactory.getLogger(EidasAttributeRegistry.class);
- @Autowired
- private IConfigurationWithSP basicConfig;
-
- private AttributeRegistry coreAttributeRegistry;
-
- private String eidasAttributesFile;
- private String additionalAttributesFile;
-
- @PostConstruct
- private void initialize() throws RuntimeException {
- try {
- if (eidasAttributesFile.isEmpty()) {
- log.error("Basic eIDAS addribute definition NOT defined");
- throw new EaafConfigurationException("config.30",
- new Object[] { "eidas-attributes.xml" });
-
- }
-
- boolean additionalAttrAvailabe = false;
- if (!additionalAttributesFile.isEmpty()) {
- final File file = new File(additionalAttributesFile);
- if (file.exists()) {
- additionalAttrAvailabe = true;
- }
-
- }
-
- if (!additionalAttrAvailabe) {
- log.info("Start eIDAS ref. impl. Core without additional eIDAS attribute definitions ... ");
- coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null);
-
- } else {
- // load attribute definitions
- log.info("Start eIDAS ref. impl. Core with additional eIDAS attribute definitions ... ");
- coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null,
- additionalAttributesFile);
-
- }
-
- } catch (final Throwable e) {
- log.error("Can NOT initialize eIDAS attribute definition.", e);
- throw new RuntimeException("Can NOT initialize eIDAS attribute definition.", e);
-
- }
- }
-
- public AttributeRegistry getCoreAttributeRegistry() {
- return coreAttributeRegistry;
- }
-
- /**
- * Get Map of attributes that are requested by default.
- *
- * @return Map of AttributeIdentifier, isRequired flag
- */
- @NonNull
- public Map<String, Boolean> getDefaultAttributeSetFromConfiguration() {
- /*
- * TODO: select set for representation if mandates should be used. It's an open
- * task in respect to requested eIDAS attributes and isRequired flag, because
- * there can be a decision problem in case of natural or legal person
- * representation! From an Austrian use-case point of view, an Austrian service
- * provider can support mandates for natural and legal persons at the same time.
- * However, we CAN NOT request attributes for natural AND legal persons on the
- * same time, because it's not possible to represent both simultaneously.
- */
- final Map<String, String> configAttributes =
- basicConfig.getBasicConfigurationWithPrefix(
- Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL);
- return processAttributeInfosFromConfig(configAttributes);
-
- }
-
- /**
- * Get a Map of attributes that are additionally requested for a specific country.
- *
- * @param countryCode Country Code
- * @return Map of AttributeIdentifier, isRequired flag
- */
- @NonNull
- public Map<String, Boolean> getAttributeSetFromConfiguration(String countryCode) {
-
- /*
- * TODO: select set for representation if mandates should be used. It's an open
- * task in respect to requested eIDAS attributes and isRequired flag, because
- * there can be a decision problem in case of natural or legal person
- * representation! From an Austrian use-case point of view, an Austrian service
- * provider can support mandates for natural and legal persons at the same time.
- * However, we CAN NOT request attributes for natural AND legal persons on the
- * same time, because it's not possible to represent both simultaneously.
- */
- final Map<String, String> configAttributes =
- basicConfig.getBasicConfigurationWithPrefix(
- MessageFormat.format(
- Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL,
- countryCode.toLowerCase()));
- return processAttributeInfosFromConfig(configAttributes);
-
- }
-
- private Map<String, Boolean> processAttributeInfosFromConfig(Map<String, String> configAttributes) {
-
- final Map<String, Boolean> result = new HashMap<>();
- for (final String el : configAttributes.values()) {
- if (StringUtils.isNotEmpty(el.trim())) {
- final List<String> attrDef = KeyValueUtils.getListOfCsvValues(el.trim());
- boolean isRequired = false;
- if (attrDef.size() == 2) {
- isRequired = Boolean.parseBoolean(attrDef.get(1));
- }
-
- result.put(attrDef.get(0), isRequired);
-
- }
- }
-
- log.trace("Load #" + result.size() + " requested attributes from configuration");
- return result;
-
- }
-
- public void setEidasAttributesFile(String eidasAttributesFile) {
- this.eidasAttributesFile = eidasAttributesFile;
- }
-
- public void setAdditionalAttributesFile(String additionalAttributesFile) {
- this.additionalAttributesFile = additionalAttributesFile;
- }
-
-}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java
index f3e2adc4..2379f39e 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java
@@ -146,6 +146,7 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask {
}
}
+
private void storeGenericInfoToSession(SimpleEidasData eidData) throws EaafStorageException {
AuthProcessDataWrapper authProcessData = MatchingTaskUtils.getAuthProcessDataWrapper(pendingReq);
authProcessData.setForeigner(true);
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java
index 849f8136..535c2958 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java
@@ -44,6 +44,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
@@ -122,7 +123,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token);
workaroundRelayState(lightAuthnReq);
final String forwardUrl = selectForwardUrl(environment);
-
+
String configValue = basicConfig.getBasicConfiguration(
Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, Constants.FORWARD_METHOD_GET);
boolean useHttpRedirect = configValue.equals(Constants.FORWARD_METHOD_GET);
@@ -131,6 +132,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
} else {
sendPost(request, response, tokenBase64, forwardUrl);
+
}
revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.EIDAS_NODE_CONNECTED, lightAuthnReq.getId());
@@ -212,19 +214,20 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
@NotNull
private String selectForwardUrl(String environment) throws EaafConfigurationException {
- String result = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL);
+ String result = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL);
if (StringUtils.isNotEmpty(environment)) {
result = selectedForwardUrlForEnvironment(environment);
}
if (StringUtils.isEmpty(result)) {
log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops");
throw new EaafConfigurationException("config.08", new Object[]{
- environment == null ? Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL
- : Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL + "." + environment
+ environment == null ? Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL
+ : Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL + "." + environment
});
}
log.debug("ForwardURL: {} selected to forward eIDAS request", result);
return result;
+
}
@@ -256,19 +259,27 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
private String selectedForwardUrlForEnvironment(String environment) {
log.trace("Starting endpoint selection process for environment: {} ... ", environment);
if (environment.equalsIgnoreCase(MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_PRODUCTION)) {
- return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL);
+ return basicConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL);
+
} else if (environment.equalsIgnoreCase(MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_QS)) {
- return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL
+ return basicConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL
+ "." + MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_QS);
- } else if (environment.equalsIgnoreCase(MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING)) {
- return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL
+
+ } else if (environment.equalsIgnoreCase(
+ MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING)) {
+ return basicConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL
+ "." + MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING);
- } else if (environment.equalsIgnoreCase(MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT)) {
- return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL
+
+ } else if (environment.equalsIgnoreCase(
+ MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT)) {
+ return basicConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL
+ "." + MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT);
+
}
+
log.info("Environment selector: {} is not supported", environment);
return null;
+
}
private void sendRedirect(HttpServletResponse response, String tokenBase64, String forwardUrl) throws IOException {
@@ -283,11 +294,11 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
throws GuiBuildException {
log.debug("Use http-post for eIDAS node forwarding ... ");
final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
- basicConfig, pendingReq, Constants.TEMPLATE_POST_FORWARD_NAME, null, resourceLoader);
- config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl);
+ basicConfig, pendingReq, EidasConstants.TEMPLATE_POST_FORWARD_NAME, null, resourceLoader);
+ config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl);
String token = EidasParameterKeys.TOKEN.toString();
- config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME, token);
- config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, tokenBase64);
+ config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_TOKEN_NAME, token);
+ config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, tokenBase64);
guiBuilder.build(request, response, config, "Forward to eIDASNode form");
}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java
index 09ef0129..403c3355 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java
@@ -158,6 +158,7 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthS
} else {
log.debug("Find single match by using residence information. Starting data validation ... ");
compareSearchResultWithInitialData(residencyResult, eidasData);
+ executionContext.put(TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK, false);
}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseAlternativeTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseAlternativeTask.java
index d2bd0128..ac70a2ac 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseAlternativeTask.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseAlternativeTask.java
@@ -39,8 +39,9 @@ import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasValidationException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.validator.EidasResponseValidator;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
@@ -135,7 +136,7 @@ public class ReceiveAuthnResponseAlternativeTask extends AbstractAuthServletTask
}
private void checkStatusCode(ILightResponse eidasResponse) throws EidasSAuthenticationException {
- if (!eidasResponse.getStatus().getStatusCode().equals(Constants.SUCCESS_URI)) {
+ if (!eidasResponse.getStatus().getStatusCode().equals(EidasConstants.SUCCESS_URI)) {
log.info("Receive eIDAS Response with StatusCode: {} Subcode: {} Msg: {}",
eidasResponse.getStatus().getStatusCode(),
eidasResponse.getStatus().getSubStatusCode(),
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java
index 5e4075de..a16da17f 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java
@@ -40,8 +40,9 @@ import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasValidationException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.validator.EidasResponseValidator;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
@@ -162,17 +163,20 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask {
return eidasResponse;
}
+
private void checkStatusCode(ILightResponse eidasResponse) throws EidasSAuthenticationException {
- if (!eidasResponse.getStatus().getStatusCode().equals(Constants.SUCCESS_URI)) {
+ if (!eidasResponse.getStatus().getStatusCode().equals(EidasConstants.SUCCESS_URI)) {
log.info("Receive eIDAS Response with StatusCode: {} Subcode: {} Msg: {}",
eidasResponse.getStatus().getStatusCode(),
eidasResponse.getStatus().getSubStatusCode(),
eidasResponse.getStatus().getStatusMessage());
throw new EidasSAuthenticationException("eidas.02", new Object[]{eidasResponse.getStatus()
.getStatusCode(), eidasResponse.getStatus().getStatusMessage()});
+
}
}
+
private void validateMsSpecificResponse(ExecutionContext executionContext, ILightResponse eidasResponse)
throws EidasValidationException {
final String spCountry = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT");
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
index 2853d8ab..91a6ce42 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
@@ -38,8 +38,8 @@ import org.joda.time.DateTime;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
import at.gv.egiz.eaaf.core.impl.data.Triple;
import eu.eidas.auth.commons.attribute.AttributeDefinition;
@@ -84,8 +84,9 @@ public class EidasResponseUtils {
*/
public static Triple<String, String, String> parseEidasPersonalIdentifier(String uniqueID) {
if (!validateEidasPersonalIdentifier(uniqueID)) {
- log.error("eIDAS attribute value for {} looks wrong formated. Value: {}",
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER, uniqueID);
+ log.error("eIDAS attribute value for {} looks wrong formated. Value: {}",
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, uniqueID);
+
return null;
}
@@ -210,11 +211,11 @@ public class EidasResponseUtils {
// TODO: add more mappings
return result;
} else {
- log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type");
- throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS);
+ log.warn("eIDAS attr: " + EidasConstants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type");
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_CURRENTADDRESS);
}
} else {
- log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... ");
+ log.debug("NO '" + EidasConstants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... ");
}
return null;
}
@@ -231,11 +232,11 @@ public class EidasResponseUtils {
if (birthNameObj instanceof String) {
return (String) birthNameObj;
} else {
- log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type");
- throw new EidasAttributeException(Constants.eIDAS_ATTR_BIRTHNAME);
+ log.warn("eIDAS attr: " + EidasConstants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type");
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_BIRTHNAME);
}
} else {
- log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... ");
+ log.debug("NO '" + EidasConstants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... ");
}
return null;
}
@@ -253,13 +254,13 @@ public class EidasResponseUtils {
return (String) placeOfBirthObj;
} else {
- log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type");
- throw new EidasAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH);
+ log.warn("eIDAS attr: " + EidasConstants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type");
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_PLACEOFBIRTH);
}
} else {
- log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... ");
+ log.debug("NO '" + EidasConstants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... ");
}
return null;
}
@@ -273,7 +274,7 @@ public class EidasResponseUtils {
*/
public static DateTime processDateOfBirth(Object dateOfBirthObj) throws EidasAttributeException {
if (!(dateOfBirthObj instanceof DateTime)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_DATEOFBIRTH);
}
return (DateTime) dateOfBirthObj;
}
@@ -291,11 +292,11 @@ public class EidasResponseUtils {
new SimpleDateFormat("yyyy-MM-dd").parse((String) dateOfBirthObj);
return (String) dateOfBirthObj;
} catch (ParseException e) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_DATEOFBIRTH);
}
}
if (!(dateOfBirthObj instanceof DateTime)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_DATEOFBIRTH);
}
return new SimpleDateFormat("yyyy-MM-dd").format(((DateTime) dateOfBirthObj).toDate());
}
@@ -309,7 +310,7 @@ public class EidasResponseUtils {
*/
public static String processGivenName(Object givenNameObj) throws EidasAttributeException {
if (!(givenNameObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME);
}
return (String) givenNameObj;
}
@@ -323,7 +324,7 @@ public class EidasResponseUtils {
*/
public static String processFamilyName(Object familyNameObj) throws EidasAttributeException {
if (!(familyNameObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME);
}
return (String) familyNameObj;
}
@@ -337,7 +338,7 @@ public class EidasResponseUtils {
*/
public static String processPersonalIdentifier(Object personalIdentifierObj) throws EidasAttributeException {
if (!(personalIdentifierObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
}
return (String) personalIdentifierObj;
}
@@ -352,7 +353,7 @@ public class EidasResponseUtils {
*/
public static String processPseudonym(Object personalIdObj) throws EidasAttributeException {
if (!(personalIdObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
}
final Triple<String, String, String> eIdentifier =
EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj);
@@ -371,7 +372,7 @@ public class EidasResponseUtils {
*/
public static String processCountryCode(Object personalIdObj) throws EidasAttributeException {
if (!(personalIdObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER);
}
final Triple<String, String, String> eIdentifier =
EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj);
@@ -390,7 +391,7 @@ public class EidasResponseUtils {
*/
public static String processTaxReference(Object taxReferenceObj) throws EidasAttributeException {
if (!(taxReferenceObj instanceof String)) {
- throw new EidasAttributeException(Constants.eIDAS_ATTR_TAXREFERENCE);
+ throw new EidasAttributeException(EidasConstants.eIDAS_ATTR_TAXREFERENCE);
}
return (String) taxReferenceObj;
}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/validator/EidasResponseValidator.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/validator/EidasResponseValidator.java
index 9d9a0647..d1962654 100644
--- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/validator/EidasResponseValidator.java
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/validator/EidasResponseValidator.java
@@ -31,10 +31,10 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableSet;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasValidationException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.impl.data.Triple;
import eu.eidas.auth.commons.attribute.AttributeDefinition;
@@ -97,7 +97,7 @@ public class EidasResponseValidator {
*_____________________________________________________|
*/
final AttributeDefinition<?> attrDefinition = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final ImmutableSet<? extends AttributeValue<?>> attributeValues = eidasResponse.getAttributes()
.getAttributeMap().get(attrDefinition);
final List<String> personalIdObj = EidasResponseUtils.translateStringListAttribute(attrDefinition,
@@ -123,48 +123,48 @@ public class EidasResponseValidator {
if (split == null) {
throw new EidasValidationException("eidas.07",
new Object[] {
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
"Wrong identifier format" });
} else {
// validation according to eIDAS SAML Attribute Profile, Section 2.2.3
if (StringUtils.isEmpty(split.getSecond())) {
- log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ log.warn("eIDAS attribute value for " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER
+ " includes NO destination country. Value:" + natPersId);
throw new EidasValidationException("eidas.07",
new Object[] {
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
"No or empty destination country" });
}
if (!split.getSecond().equalsIgnoreCase(spCountry)) {
- log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ log.warn("eIDAS attribute value for " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER
+ " includes wrong destination country. Value:" + natPersId
+ " SP-Country:" + spCountry);
throw new EidasValidationException("eidas.07",
new Object[] {
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
"Destination country does not match to SP country" });
}
if (StringUtils.isEmpty(split.getFirst())) {
- log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ log.warn("eIDAS attribute value for " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER
+ " includes NO citizen country. Value:" + natPersId);
throw new EidasValidationException("eidas.07",
new Object[] {
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
"No or empty citizen country" });
}
if (!split.getFirst().equalsIgnoreCase(citizenCountryCode)) {
- log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ log.warn("eIDAS attribute value for " + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER
+ " includes a citizen country that does not match to service-provider country. "
+ " Value:" + natPersId
+ " citiczen Country:" + spCountry);
throw new EidasValidationException("eidas.07",
new Object[] {
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
"Citizen country does not match to eIDAS-node country that generates the response" });
}
diff --git a/modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
index 193513b0..ab4228fd 100644
--- a/modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
+++ b/modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
@@ -38,13 +38,16 @@
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasSignalServlet" />
<bean id="attributeRegistry"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry">
+ class="at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry">
<property name="eidasAttributesFile"
ref="specificConnectorAttributesFileWithPath" />
<property name="additionalAttributesFile"
ref="specificConnectorAdditionalAttributesFileWithPath" />
</bean>
+ <bean id="connectorAttributeRegistry"
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ConnectorEidasAttributeRegistry" />
+
<!-- <bean id="eIDASDataStore" class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.eIDASDataStore"
/> -->
@@ -55,17 +58,22 @@
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.CcSpecificEidProcessingService" />
<bean id="DE-Processor"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.DeEidProcessor">
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.DeEidProcessor">
<property name="priority" value="1" />
</bean>
<bean id="LU-Processor"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.LuEidProcessor">
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.LuEidProcessor">
+ <property name="priority" value="1" />
+ </bean>
+
+ <bean id="NL-Processor"
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.NlEidProcessor">
<property name="priority" value="1" />
</bean>
<bean id="Default-Processor"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.GenericEidProcessor">
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.GenericEidProcessor">
<property name="priority" value="0" />
</bean>
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasSignalServletTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasSignalServletTest.java
index 4d4ac47d..3bc06092 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasSignalServletTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasSignalServletTest.java
@@ -29,7 +29,8 @@ import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfi
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasSignalServlet;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
@@ -138,7 +139,7 @@ public class EidasSignalServletTest {
iLightResponse.id("_".concat(Random.nextHexRandom16()))
.issuer(RandomStringUtils.randomAlphabetic(10))
.subject(RandomStringUtils.randomAlphabetic(10))
- .statusCode(Constants.SUCCESS_URI)
+ .statusCode(EidasConstants.SUCCESS_URI)
.inResponseTo("_".concat(Random.nextHexRandom16()))
.subjectNameIdFormat("afaf")
.relayState(relayState);
@@ -177,7 +178,7 @@ public class EidasSignalServletTest {
iLightResponse.id("_".concat(Random.nextHexRandom16()))
.issuer(RandomStringUtils.randomAlphabetic(10))
.subject(RandomStringUtils.randomAlphabetic(10))
- .statusCode(Constants.SUCCESS_URI)
+ .statusCode(EidasConstants.SUCCESS_URI)
.inResponseTo(inResponseTo)
.subjectNameIdFormat("afaf");
@@ -213,7 +214,7 @@ public class EidasSignalServletTest {
iLightResponse.id("_".concat(Random.nextHexRandom16()))
.issuer(RandomStringUtils.randomAlphabetic(10))
.subject(RandomStringUtils.randomAlphabetic(10))
- .statusCode(Constants.SUCCESS_URI)
+ .statusCode(EidasConstants.SUCCESS_URI)
.inResponseTo(inResponseTo)
.subjectNameIdFormat("afaf");
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java
index cb9df7e5..af1867e7 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java
@@ -19,12 +19,12 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.LoggingHandler;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.EidasSuchdatenType;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest;
import at.gv.e_government.reference.namespace.persondata.de._20040201.NatuerlichePersonTyp;
@@ -453,9 +453,9 @@ public class ZmrClientProductionTest {
searchNatPerson.setGeburtsdatum(dateOfBirth);
// add addtional eIDAS attributes if available
- addIfAvailable(req.getEidasSuchdaten(), cc, Constants.eIDAS_ATTRURN_PLACEOFBIRTH, placeOfBirth);
- addIfAvailable(req.getEidasSuchdaten(), cc, Constants.eIDAS_ATTRURN_BIRTHNAME, birthName);
- addIfAvailable(req.getEidasSuchdaten(), cc, Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, personalId);
+ addIfAvailable(req.getEidasSuchdaten(), cc, EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH, placeOfBirth);
+ addIfAvailable(req.getEidasSuchdaten(), cc, EidasConstants.eIDAS_ATTRURN_BIRTHNAME, birthName);
+ addIfAvailable(req.getEidasSuchdaten(), cc, EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER, personalId);
return req;
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java
index 4e0a1f28..ef9cc9b7 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java
@@ -38,7 +38,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.github.skjolber.mockito.soap.SoapServiceRule;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput;
@@ -46,6 +45,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.base._20040201.RequestType;
import at.gv.bmi.namespace.zmr_su.base._20040201.ResponseType;
import at.gv.bmi.namespace.zmr_su.base._20040201_.ServicePort;
@@ -1139,9 +1139,9 @@ public class ZmrClientTest {
searchNatPerson.setGeburtsdatum(dateOfBirth);
// add addtional eIDAS attributes if available
- addIfAvailable(req.getEidasSuchdaten(), cc, Constants.eIDAS_ATTRURN_PLACEOFBIRTH, placeOfBirth);
- addIfAvailable(req.getEidasSuchdaten(), cc, Constants.eIDAS_ATTRURN_BIRTHNAME, birthName);
- addIfAvailable(req.getEidasSuchdaten(), cc, Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, personalId);
+ addIfAvailable(req.getEidasSuchdaten(), cc, EidasConstants.eIDAS_ATTRURN_PLACEOFBIRTH, placeOfBirth);
+ addIfAvailable(req.getEidasSuchdaten(), cc, EidasConstants.eIDAS_ATTRURN_BIRTHNAME, birthName);
+ addIfAvailable(req.getEidasSuchdaten(), cc, EidasConstants.eIDAS_ATTRURN_PERSONALIDENTIFIER, personalId);
return req;
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java
index 682db41e..176e95cb 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java
@@ -67,6 +67,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchSe
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.AlternativeSearchTask;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients.ZmrClientTest;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.base._20040201.RequestType;
import at.gv.bmi.namespace.zmr_su.base._20040201.ResponseType;
import at.gv.bmi.namespace.zmr_su.base._20040201_.ServicePort;
@@ -913,24 +914,24 @@ public class AlternativeSearchTaskWithRegisterTest {
String dateOfBirth, String taxNumber, String placeOfBirth,
String birthName) throws URISyntaxException {
ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder()
- .put(generateStringAttribute(Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
randomAlphabetic(2), randomAlphabetic(2)), identifier)
- .put(generateStringAttribute(Constants.eIDAS_ATTR_CURRENTFAMILYNAME,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME,
randomAlphabetic(3), randomAlphabetic(3)), familyName)
- .put(generateStringAttribute(Constants.eIDAS_ATTR_CURRENTGIVENNAME,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME,
randomAlphabetic(4), randomAlphabetic(4)), givenName)
- .put(generateDateTimeAttribute(Constants.eIDAS_ATTR_DATEOFBIRTH,
+ .put(generateDateTimeAttribute(EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
randomAlphabetic(5), randomAlphabetic(5)), dateOfBirth);
if (taxNumber != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_TAXREFERENCE,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_TAXREFERENCE,
randomAlphabetic(6), randomAlphabetic(6)), taxNumber);
}
if (birthName != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_BIRTHNAME,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_BIRTHNAME,
randomAlphabetic(7), randomAlphabetic(7)), birthName);
}
if (placeOfBirth != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_PLACEOFBIRTH,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_PLACEOFBIRTH,
randomAlphabetic(8), randomAlphabetic(8)), placeOfBirth);
}
final ImmutableAttributeMap attributeMap = builder.build();
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java
index 023c196c..36c0c2af 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java
@@ -57,13 +57,14 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.SzrCommunicationException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.JoseUtils;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.JoseUtils.JwsResult;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
@@ -605,18 +606,18 @@ public class CreateIdentityLinkTaskEidNewTest {
@Nonnull
private AuthenticationResponse buildDummyAuthResponse(boolean withAll, boolean withEmpty) throws URISyntaxException {
final AttributeDefinition attributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final AttributeDefinition attributeDef2 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
final AttributeDefinition attributeDef3 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTGIVENNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first();
final AttributeDefinition attributeDef4 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_DATEOFBIRTH).first();
+ EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first();
final AttributeDefinition attributeDef5 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PLACEOFBIRTH).first();
+ EidasConstants.eIDAS_ATTR_PLACEOFBIRTH).first();
final AttributeDefinition attributeDef6 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_BIRTHNAME).first();
-
+ EidasConstants.eIDAS_ATTR_BIRTHNAME).first();
+
final Builder attributeMap = ImmutableAttributeMap.builder();
attributeMap.put(attributeDef, "LU/AT/" + RandomStringUtils.randomNumeric(64));
attributeMap.put(attributeDef2, RandomStringUtils.randomAlphabetic(10));
@@ -638,7 +639,7 @@ public class CreateIdentityLinkTaskEidNewTest {
return b.id("_".concat(Random.nextHexRandom16()))
.issuer(RandomStringUtils.randomAlphabetic(10))
.subject(RandomStringUtils.randomAlphabetic(10))
- .statusCode(Constants.SUCCESS_URI)
+ .statusCode(EidasConstants.SUCCESS_URI)
.inResponseTo("_".concat(Random.nextHexRandom16()))
.subjectNameIdFormat("afaf")
.levelOfAssurance(EaafConstants.EIDAS_LOA_PREFIX + RandomStringUtils.randomAlphabetic(5))
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java
index 5c528532..5db6e95d 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java
@@ -41,11 +41,12 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MatchedPersonResult;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
@@ -475,13 +476,13 @@ public class CreateIdentityLinkTaskTest {
@NotNull
private AuthenticationResponse buildDummyAuthResponse() throws URISyntaxException {
final AttributeDefinition attributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final AttributeDefinition attributeDef2 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
final AttributeDefinition attributeDef3 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTGIVENNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first();
final AttributeDefinition attributeDef4 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_DATEOFBIRTH).first();
+ EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first();
final ImmutableAttributeMap attributeMap = ImmutableAttributeMap.builder()
.put(attributeDef, "LU/AT/" + RandomStringUtils.randomNumeric(64))
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java
index 763d7d39..761738aa 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java
@@ -26,7 +26,8 @@ import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigM
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.GenerateAuthnRequestTask;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
@@ -138,7 +139,7 @@ public class GenerateAuthnRequestTaskTest {
.getErrorId());
Assert.assertEquals("wrong parameter size", 1, ((EaafException) e.getOriginalException())
.getParams().length);
- Assert.assertEquals("wrong errorMsg", Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL, ((EaafException) e
+ Assert.assertEquals("wrong errorMsg", EidasConstants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL, ((EaafException) e
.getOriginalException()).getParams()[0]);
}
@@ -163,7 +164,7 @@ public class GenerateAuthnRequestTaskTest {
.getErrorId());
Assert.assertEquals("wrong parameter size", 1, ((EaafException) e.getOriginalException())
.getParams().length);
- Assert.assertEquals("wrong errorMsg", Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL + "." + stage, ((EaafException) e
+ Assert.assertEquals("wrong errorMsg", EidasConstants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL + "." + stage, ((EaafException) e
.getOriginalException()).getParams()[0]);
}
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java
index 74ac065e..eef31a02 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java
@@ -83,6 +83,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchSe
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.InitialSearchTask;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
@@ -887,24 +888,24 @@ public class InitialSearchTaskTest {
String dateOfBirth, String taxNumber, String placeOfBirth,
String birthName) throws URISyntaxException {
ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder()
- .put(generateStringAttribute(Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
randomAlphabetic(2), randomAlphabetic(2)), identifier)
- .put(generateStringAttribute(Constants.eIDAS_ATTR_CURRENTFAMILYNAME,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME,
randomAlphabetic(3), randomAlphabetic(3)), familyName)
- .put(generateStringAttribute(Constants.eIDAS_ATTR_CURRENTGIVENNAME,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME,
randomAlphabetic(4), randomAlphabetic(4)), givenName)
- .put(generateDateTimeAttribute(Constants.eIDAS_ATTR_DATEOFBIRTH,
+ .put(generateDateTimeAttribute(EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
randomAlphabetic(5), randomAlphabetic(5)), dateOfBirth);
if (taxNumber != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_TAXREFERENCE,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_TAXREFERENCE,
randomAlphabetic(6), randomAlphabetic(6)), taxNumber);
}
if (birthName != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_BIRTHNAME,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_BIRTHNAME,
randomAlphabetic(7), randomAlphabetic(7)), birthName);
}
if (placeOfBirth != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_PLACEOFBIRTH,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_PLACEOFBIRTH,
randomAlphabetic(8), randomAlphabetic(8)), placeOfBirth);
}
final ImmutableAttributeMap attributeMap = builder.build();
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java
index 6d0e7c31..4b9e9fe2 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java
@@ -88,6 +88,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.InitialSearchTask;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients.ErnpRestClientTest;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients.ZmrClientTest;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.gv.bmi.namespace.zmr_su.base._20040201.RequestType;
import at.gv.bmi.namespace.zmr_su.base._20040201.ResponseType;
import at.gv.bmi.namespace.zmr_su.base._20040201_.ServicePort;
@@ -607,24 +608,24 @@ public class InitialSearchTaskWithRegistersTest {
String dateOfBirth, String taxNumber, String placeOfBirth,
String birthName) throws URISyntaxException {
ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder()
- .put(generateStringAttribute(Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
randomAlphabetic(2), randomAlphabetic(2)), identifier)
- .put(generateStringAttribute(Constants.eIDAS_ATTR_CURRENTFAMILYNAME,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME,
randomAlphabetic(3), randomAlphabetic(3)), familyName)
- .put(generateStringAttribute(Constants.eIDAS_ATTR_CURRENTGIVENNAME,
+ .put(generateStringAttribute(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME,
randomAlphabetic(4), randomAlphabetic(4)), givenName)
- .put(generateDateTimeAttribute(Constants.eIDAS_ATTR_DATEOFBIRTH,
+ .put(generateDateTimeAttribute(EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
randomAlphabetic(5), randomAlphabetic(5)), dateOfBirth);
if (taxNumber != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_TAXREFERENCE,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_TAXREFERENCE,
randomAlphabetic(6), randomAlphabetic(6)), taxNumber);
}
if (birthName != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_BIRTHNAME,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_BIRTHNAME,
randomAlphabetic(7), randomAlphabetic(7)), birthName);
}
if (placeOfBirth != null) {
- builder.put(generateStringAttribute(Constants.eIDAS_ATTR_PLACEOFBIRTH,
+ builder.put(generateStringAttribute(EidasConstants.eIDAS_ATTR_PLACEOFBIRTH,
randomAlphabetic(8), randomAlphabetic(8)), placeOfBirth);
}
final ImmutableAttributeMap attributeMap = builder.build();
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAuthnResponseTaskTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAuthnResponseTaskTest.java
index 842c8bf7..53f83095 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAuthnResponseTaskTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAuthnResponseTaskTest.java
@@ -27,8 +27,9 @@ import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAuthnResponseTask;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
@@ -142,7 +143,7 @@ public class ReceiveAuthnResponseTaskTest {
public void successAndForward() throws URISyntaxException, TaskExecutionException,
PendingReqIdValidationException, EaafStorageException {
- AuthenticationResponse eidasResponse = buildDummyAuthResponse(Constants.SUCCESS_URI);
+ AuthenticationResponse eidasResponse = buildDummyAuthResponse(EidasConstants.SUCCESS_URI);
httpReq.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
String alternativReturnEndpoint = "http://ms-connector.alternative/" + RandomStringUtils.randomAlphabetic(10);
@@ -172,7 +173,7 @@ public class ReceiveAuthnResponseTaskTest {
public void success() throws URISyntaxException, TaskExecutionException, PendingReqIdValidationException {
@Nonnull
- AuthenticationResponse eidasResponse = buildDummyAuthResponse(Constants.SUCCESS_URI);
+ AuthenticationResponse eidasResponse = buildDummyAuthResponse(EidasConstants.SUCCESS_URI);
httpReq.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
executionContext.put(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY, "LU");
@@ -200,7 +201,7 @@ public class ReceiveAuthnResponseTaskTest {
basicConfig.putConfigValue("eidas.ms.auth.eIDAS.eid.testidentity.default", "true");
@Nonnull
- AuthenticationResponse eidasResponse = buildDummyAuthResponse(Constants.SUCCESS_URI);
+ AuthenticationResponse eidasResponse = buildDummyAuthResponse(EidasConstants.SUCCESS_URI);
httpReq.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
executionContext.put(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY, "LU");
@@ -226,13 +227,13 @@ public class ReceiveAuthnResponseTaskTest {
@Nonnull
private AuthenticationResponse buildDummyAuthResponse(String statusCode) throws URISyntaxException {
final AttributeDefinition attributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final AttributeDefinition attributeDef2 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
final AttributeDefinition attributeDef3 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTGIVENNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first();
final AttributeDefinition attributeDef4 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_DATEOFBIRTH).first();
+ EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first();
final ImmutableAttributeMap attributeMap = ImmutableAttributeMap.builder()
.put(attributeDef, "LU/AT/" + RandomStringUtils.randomNumeric(64))
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveEidasResponseTaskTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveEidasResponseTaskTest.java
index 4148b138..4112e047 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveEidasResponseTaskTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveEidasResponseTaskTest.java
@@ -27,8 +27,9 @@ import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAuthnResponseAlternativeTask;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.IRequestStorage;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
@@ -141,7 +142,7 @@ public class ReceiveEidasResponseTaskTest {
public void successAndForward() throws URISyntaxException, TaskExecutionException,
PendingReqIdValidationException, EaafStorageException {
- AuthenticationResponse eidasResponse = buildDummyAuthResponse(Constants.SUCCESS_URI);
+ AuthenticationResponse eidasResponse = buildDummyAuthResponse(EidasConstants.SUCCESS_URI);
httpReq.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
String alternativReturnEndpoint = "http://ms-connector.alternative/" + RandomStringUtils.randomAlphabetic(10);
@@ -171,7 +172,7 @@ public class ReceiveEidasResponseTaskTest {
public void success() throws URISyntaxException, TaskExecutionException, PendingReqIdValidationException {
@Nonnull
- AuthenticationResponse eidasResponse = buildDummyAuthResponse(Constants.SUCCESS_URI);
+ AuthenticationResponse eidasResponse = buildDummyAuthResponse(EidasConstants.SUCCESS_URI);
httpReq.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
//execute test
@@ -198,7 +199,7 @@ public class ReceiveEidasResponseTaskTest {
basicConfig.putConfigValue("eidas.ms.auth.eIDAS.eid.testidentity.default", "true");
@Nonnull
- AuthenticationResponse eidasResponse = buildDummyAuthResponse(Constants.SUCCESS_URI);
+ AuthenticationResponse eidasResponse = buildDummyAuthResponse(EidasConstants.SUCCESS_URI);
httpReq.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
//execute test
@@ -223,14 +224,14 @@ public class ReceiveEidasResponseTaskTest {
@Nonnull
private AuthenticationResponse buildDummyAuthResponse(String statusCode) throws URISyntaxException {
final AttributeDefinition attributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final AttributeDefinition attributeDef2 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
final AttributeDefinition attributeDef3 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_CURRENTGIVENNAME).first();
+ EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first();
final AttributeDefinition attributeDef4 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_DATEOFBIRTH).first();
-
+ EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first();
+
final ImmutableAttributeMap attributeMap = ImmutableAttributeMap.builder()
.put(attributeDef, "LU/AT/" + RandomStringUtils.randomNumeric(64))
.put(attributeDef2, RandomStringUtils.randomAlphabetic(10))
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java
index 16efd84b..b8cb0642 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java
@@ -40,12 +40,13 @@ import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.CcSpecificEidProcessingService;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import lombok.SneakyThrows;
+
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"/SpringTest-context_tasks_test.xml",
@@ -352,12 +353,12 @@ public class EidasAttributePostProcessingTest {
private Map<String, Object> generateInputData(String id, String familyName, String givenName,
String dateOfBirth, String placeOfBirth, String birthName) {
final Map<String, Object> result = new HashMap<>();
- result.put(Constants.eIDAS_ATTR_PERSONALIDENTIFIER, id);
- result.put(Constants.eIDAS_ATTR_CURRENTGIVENNAME, givenName);
- result.put(Constants.eIDAS_ATTR_CURRENTFAMILYNAME, familyName);
- result.put(Constants.eIDAS_ATTR_DATEOFBIRTH, dateOfBirth);
- result.put(Constants.eIDAS_ATTR_PLACEOFBIRTH, placeOfBirth);
- result.put(Constants.eIDAS_ATTR_BIRTHNAME, birthName);
+ result.put(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, id);
+ result.put(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, givenName);
+ result.put(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, familyName);
+ result.put(EidasConstants.eIDAS_ATTR_DATEOFBIRTH, dateOfBirth);
+ result.put(EidasConstants.eIDAS_ATTR_PLACEOFBIRTH, placeOfBirth);
+ result.put(EidasConstants.eIDAS_ATTR_BIRTHNAME, birthName);
return result;
}
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java
index 84da2344..ca292d4c 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java
@@ -69,8 +69,9 @@ public class EidasRequestPreProcessingFirstTest {
private TestRequestImpl pendingReq;
private DummySpConfiguration oaParam;
- private Builder authnRequestBuilder;
-
+ private Builder authnRequestBuilder;
+ private Map<String, String> spConfig;
+
/**
* jUnit class initializer.
*
@@ -91,9 +92,9 @@ public class EidasRequestPreProcessingFirstTest {
@Before
public void setUp() {
- final Map<String, String> spConfig = new HashMap<>();
+ spConfig = new HashMap<>();
spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp");
- spConfig.put("target", "urn:publicid:gv.at:cdid+XX");
+ spConfig.put("target", "urn:publicid:gv.at:cdid+XX");
oaParam = new DummySpConfiguration(spConfig, basicConfig);
pendingReq = new TestRequestImpl();
@@ -154,5 +155,42 @@ public class EidasRequestPreProcessingFirstTest {
Assert.assertEquals("Requested attribute size not match", 8, lightReq.getRequestedAttributes().size());
}
+
+ @Test
+ public void prePreProcessNlWithUpgrade() throws EidPostProcessingException {
+
+ final String testCountry = "NL";
+ spConfig.put("loa", EaafConstants.EIDAS_LOA_LOW);
+ authnRequestBuilder.citizenCountryCode(testCountry);
+ authnRequestBuilder.levelOfAssurance(EaafConstants.EIDAS_LOA_LOW);
+
+ preProcessor.preProcess(testCountry, pendingReq, authnRequestBuilder);
+
+ final LightRequest lightReq = authnRequestBuilder.build();
+
+ Assert.assertNotSame("RequesterId was set", lightReq.getRequesterId());
+ Assert.assertEquals("no PublicSP", "public", lightReq.getSpType());
+ Assert.assertEquals("Requested attribute size not match", 4, lightReq.getRequestedAttributes().size());
+
+ Assert.assertEquals("wrong LoA", EaafConstants.EIDAS_LOA_SUBSTANTIAL, lightReq.getLevelOfAssurance());
+ }
+
+ @Test
+ public void prePreProcessNlWithOutUpgrade() throws EidPostProcessingException {
+
+ final String testCountry = "NL";
+ authnRequestBuilder.citizenCountryCode(testCountry);
+ preProcessor.preProcess(testCountry, pendingReq, authnRequestBuilder);
+
+ final LightRequest lightReq = authnRequestBuilder.build();
+
+ Assert.assertNotSame("RequesterId was set", lightReq.getRequesterId());
+ Assert.assertEquals("no PublicSP", "public", lightReq.getSpType());
+ Assert.assertEquals("Requested attribute size not match", 4, lightReq.getRequestedAttributes().size());
+
+ Assert.assertEquals("wrong LoA", EaafConstants.EIDAS_LOA_HIGH, lightReq.getLevelOfAssurance());
+
+ }
+
}
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasResponseValidatorTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasResponseValidatorTest.java
index bbba56e2..91a50d28 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasResponseValidatorTest.java
+++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasResponseValidatorTest.java
@@ -21,10 +21,10 @@ import com.google.common.collect.ImmutableSet;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasValidationException;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.validator.EidasResponseValidator;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
@@ -300,7 +300,7 @@ public class EidasResponseValidatorTest {
final AttributeDefinition personIdattributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
- Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final Builder attributeMap = ImmutableAttributeMap.builder();
if (personalId != null) {
@@ -319,7 +319,7 @@ public class EidasResponseValidatorTest {
return b.id("_".concat(Random.nextHexRandom16()))
.issuer(RandomStringUtils.randomAlphabetic(10))
.subject(RandomStringUtils.randomAlphabetic(10))
- .statusCode(Constants.SUCCESS_URI)
+ .statusCode(EidasConstants.SUCCESS_URI)
.inResponseTo("_".concat(Random.nextHexRandom16()))
.subjectNameIdFormat("afaf")
.levelOfAssurance(loa)
diff --git a/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml b/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml
index f4fc72a7..d71a47dc 100644
--- a/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml
+++ b/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml
@@ -17,13 +17,13 @@
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.config.EidasConnectorMessageSource"/>
<bean id="SZRClientForeIDAS"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.szr.SzrClient" />
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.szr.SzrClient" />
<!-- <bean id="eIDASDataStore" class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.eIDASDataStore"
/> -->
<bean id="springManagedSpecificConnectorCommunicationService"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService" />
+ class="at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService" />
<bean id="specificConnectorAttributesFileWithPath"
class="java.lang.String">
@@ -38,13 +38,16 @@
</bean>
<bean id="attributeRegistry"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry">
+ class="at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry">
<property name="eidasAttributesFile"
ref="specificConnectorAttributesFileWithPath" />
<property name="additionalAttributesFile"
ref="specificConnectorAdditionalAttributesFileWithPath" />
</bean>
+ <bean id="connectorAttributeRegistry"
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ConnectorEidasAttributeRegistry" />
+
<bean id="EIDPostProcessingService"
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.service.CcSpecificEidProcessingService" />
@@ -58,6 +61,11 @@
<property name="priority" value="1" />
</bean>
+ <bean id="NL-Processor"
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.NlEidProcessor">
+ <property name="priority" value="1" />
+ </bean>
+
<bean id="eIDASAuthModule"
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasAuthenticationModulImpl">
<property name="priority" value="2" />
diff --git a/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_tasks_test.xml b/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_tasks_test.xml
index 0afa0d7d..1b5391d5 100644
--- a/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_tasks_test.xml
+++ b/modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_tasks_test.xml
@@ -25,7 +25,7 @@
class="at.gv.egiz.eaaf.core.impl.gui.builder.SpringMvcGuiFormBuilderImpl" />
<bean id="springManagedSpecificConnectorCommunicationService"
- class="at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService" />
+ class="at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService" />
<bean id="dummyPvpConfig"
class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpConfiguration" />
@@ -36,17 +36,5 @@
<bean id="dummyVelocityBuilder"
class="at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyVelocityGuiFormBuilder" />
- <bean id="specificConnectorAttributesFileWithPath"
- class="java.lang.String">
- <constructor-arg
- value="src/test/resources/config/eidas-attributes.xml" />
- </bean>
-
- <bean id="specificConnectorAdditionalAttributesFileWithPath"
- class="java.lang.String">
- <constructor-arg
- value="src/test/resources/config/additional-attributes.xml" />
- </bean>
-
</beans> \ No newline at end of file
diff --git a/modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties b/modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties
index 6d97513a..41f0fe7b 100644
--- a/modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties
+++ b/modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties
@@ -19,9 +19,9 @@ eidas.ms.revisionlog.write.MDS.into.revisionlog=true
eidas.ms.revisionlog.logIPAddressOfUser=true
##Directory for static Web content
-eidas.ms.webcontent.static.directory=../../../../../../basicConfig/webcontent/
-eidas.ms.webcontent.templates=../../../../../../basicConfig/templates/
-eidas.ms.webcontent.properties=../../../../../../basicConfig/properties/messages
+eidas.ms.webcontent.static.directory=../../../../../../basicConfig/ms-connector/webcontent/
+eidas.ms.webcontent.templates=../../../../../../basicConfig/ms-connector/templates/
+eidas.ms.webcontent.properties=../../../../../../basicConfig/ms-connector/properties/messages
## extended validation of pending-request Id's
eidas.ms.core.pendingrequestid.maxlifetime=300
diff --git a/modules/authmodule_id-austria/checks/spotbugs-exclude.xml b/modules/authmodule_id-austria/checks/spotbugs-exclude.xml
new file mode 100644
index 00000000..366c7aca
--- /dev/null
+++ b/modules/authmodule_id-austria/checks/spotbugs-exclude.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<FindBugsFilter>
+ <Match>
+ <!-- CSRF protection is implicit available by request token -->
+ <Class name="at.asitplus.eidas.specific.modules.auth.idaustria.controller.IdAustriaAuthSignalController" />
+ <Method name="performEidasAuthentication" />
+ <OR>
+ <Bug pattern="SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING" />
+ </OR>
+ </Match>
+ <!-- Logging of invalid SAML2 responses are allowed on debug level -->
+ <Match>
+ <Class name="at.asitplus.eidas.specific.modules.auth.idaustria.tasks.ReceiveFromIdAustriaSystemTask"/>
+ <Method name="execute" />
+ <OR>
+ <Bug pattern="CRLF_INJECTION_LOGS" />
+ </OR>
+ </Match>
+ <Match>
+ <!-- Builder pattern does not expose date elements -->
+ <OR>
+ <Class name="at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthRequestBuilderConfiguration" />
+ </OR>
+ <OR>
+ <Bug pattern="EI_EXPOSE_REP" />
+ <Bug pattern="EI_EXPOSE_REP2" />
+ </OR>
+ </Match>
+</FindBugsFilter>
diff --git a/modules/authmodule_id-austria/pom.xml b/modules/authmodule_id-austria/pom.xml
new file mode 100644
index 00000000..e7ade26b
--- /dev/null
+++ b/modules/authmodule_id-austria/pom.xml
@@ -0,0 +1,150 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>modules</artifactId>
+ <version>1.3.3-SNAPSHOT</version>
+ </parent>
+ <groupId>at.asitplus.eidas.ms_specific.modules</groupId>
+ <artifactId>authmodule_id-austria</artifactId>
+ <name>eIDAS-Outging IDA bridge</name>
+
+ <repositories>
+ <repository>
+ <id>eIDASNode-local</id>
+ <name>local</name>
+ <url>file:${basedir}/../../repository</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific.modules</groupId>
+ <artifactId>eidas_proxy-sevice</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ </dependency>
+
+ <!-- Third party libs -->
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite-specific-communication</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.thymeleaf</groupId>
+ <artifactId>thymeleaf-spring5</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>mockwebserver</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_core_utils</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_sp</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_idp</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_idp</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>core_common_webapp</finalName>
+
+ <plugins>
+ <!-- enable co-existence of testng and junit -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <threadCount>1</threadCount>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
+ <plugin>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ <version>${spotbugs-maven-plugin.version}</version>
+ <configuration>
+ <excludeFilterFile>checks/spotbugs-exclude.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+</project>
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java
new file mode 100644
index 00000000..57e5c706
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java
@@ -0,0 +1,123 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
+
+/**
+ * Constant values for ID Austria authentication module.
+ *
+ * @author tlenz
+ *
+ */
+public class IdAustriaAuthConstants {
+
+ private IdAustriaAuthConstants() {
+
+ }
+
+ public static final String ERRORTYPE_00 = "module.idaustria.00";
+ public static final String ERRORTYPE_01 = "module.idaustria.01";
+ public static final String ERRORTYPE_02 = "module.idaustria.02";
+ public static final String ERRORTYPE_03 = "module.idaustria.03";
+ public static final String ERRORTYPE_04 = "module.idaustria.04";
+ public static final String ERRORTYPE_05 = "module.idaustria.05";
+ public static final String ERRORTYPE_06 = "module.idaustria.06";
+ public static final String ERRORTYPE_98 = "module.idaustria.98";
+ public static final String ERRORTYPE_99 = "module.idaustria.99";
+
+
+ public static final String SAML2_STATUSCODE_USERSTOP = "1005";
+
+ public static final int METADATA_VALIDUNTIL_IN_HOURS = 24 * 365;
+ public static final String MODULE_NAME_FOR_LOGGING = "ID Austria based eIDAS authentication";
+
+ public static final String ENDPOINT_POST = "/sp/idaustria/eidas/post";
+ public static final String ENDPOINT_REDIRECT = "/sp/idaustria/eidas/redirect";
+ public static final String ENDPOINT_METADATA = "/sp/idaustria/eidas/metadata";
+
+ public static final String CONFIG_PROPS_PREFIX = "modules.idaustriaauth.";
+
+ public static final String CONFIG_PROPS_IDAUSTRIA_ENTITYID = CONFIG_PROPS_PREFIX + "idp.entityId";
+ public static final String CONFIG_PROPS_IDAUSTRIA_METADATAURL = CONFIG_PROPS_PREFIX + "idp.metadataUrl";
+
+ public static final String CONFIG_PROPS_KEYSTORE_TYPE = CONFIG_PROPS_PREFIX + "keystore.type";
+ public static final String CONFIG_PROPS_KEYSTORE_NAME = CONFIG_PROPS_PREFIX + "keystore.name";
+ public static final String CONFIG_PROPS_KEYSTORE_PATH = CONFIG_PROPS_PREFIX + "keystore.path";
+ public static final String CONFIG_PROPS_KEYSTOREPASSWORD = CONFIG_PROPS_PREFIX + "keystore.password";
+ public static final String CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD = CONFIG_PROPS_PREFIX
+ + "metadata.sign.password";
+ public static final String CONFIG_PROPS_SIGN_METADATA_ALIAS = CONFIG_PROPS_PREFIX
+ + "metadata.sign.alias";
+ public static final String CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD = CONFIG_PROPS_PREFIX
+ + "request.sign.password";
+ public static final String CONFIG_PROPS_SIGN_SIGNING_ALIAS = CONFIG_PROPS_PREFIX
+ + "request.sign.alias";
+ public static final String CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD = CONFIG_PROPS_PREFIX
+ + "response.encryption.password";
+ public static final String CONFIG_PROPS_ENCRYPTION_ALIAS = CONFIG_PROPS_PREFIX
+ + "response.encryption.alias";
+
+ public static final String CONFIG_PROPS_TRUSTSTORE_TYPE = CONFIG_PROPS_PREFIX + "truststore.type";
+ public static final String CONFIG_PROPS_TRUSTSTORE_NAME = CONFIG_PROPS_PREFIX + "truststore.name";
+ public static final String CONFIG_PROPS_TRUSTSTORE_PATH = CONFIG_PROPS_PREFIX + "truststore.path";
+ public static final String CONFIG_PROPS_TRUSTSTORE_PASSWORD = CONFIG_PROPS_PREFIX + "truststore.password";
+
+ public static final String CONFIG_PROPS_REQUIRED_PVP_ATTRIBUTES_LIST = CONFIG_PROPS_PREFIX
+ + "required.additional.attributes";
+
+
+ /**
+ * SP specific EntityId of the ID Austria.
+ */
+ public static final String CONFIG_PROPS_APPSPECIFIC_IDAUSTRIA_NODE_URL = "auth.idaustria.entityId";
+
+
+ public static final List<Triple<String, String, Boolean>> DEFAULT_REQUIRED_PVP_ATTRIBUTES =
+ Collections.unmodifiableList(new ArrayList<Triple<String, String, Boolean>>() {
+ private static final long serialVersionUID = 1L;
+ {
+ // add PVP Version attribute
+ add(Triple.newInstance(PvpAttributeDefinitions.PVP_VERSION_NAME,
+ PvpAttributeDefinitions.PVP_VERSION_FRIENDLY_NAME, false));
+
+ // entity information
+ add(Triple.newInstance(PvpAttributeDefinitions.GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.GIVEN_NAME_FRIENDLY_NAME, true));
+ add(Triple.newInstance(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME,
+ PvpAttributeDefinitions.PRINCIPAL_NAME_FRIENDLY_NAME, true));
+ add(Triple.newInstance(PvpAttributeDefinitions.BIRTHDATE_NAME,
+ PvpAttributeDefinitions.BIRTHDATE_FRIENDLY_NAME, true));
+ add(Triple.newInstance(PvpAttributeDefinitions.BPK_NAME,
+ PvpAttributeDefinitions.BPK_FRIENDLY_NAME, true));
+
+ // entity metadata information
+ add(Triple.newInstance(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME,
+ PvpAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME, true));
+ add(Triple.newInstance(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, false));
+
+ // mandate attributes
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_TYPE_NAME,
+ PvpAttributeDefinitions.MANDATE_TYPE_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_TYPE_OID_NAME,
+ PvpAttributeDefinitions.MANDATE_TYPE_OID_FRIENDLY_NAME, false));
+ addAll(MsEidasNodeConstants.DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES);
+ addAll(MsEidasNodeConstants.DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES);
+
+ }
+ });
+
+ public static final Set<String> DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES =
+ DEFAULT_REQUIRED_PVP_ATTRIBUTES.stream()
+ .filter(el -> el.getThird())
+ .map(el -> el.getFirst())
+ .collect(Collectors.toSet());
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthenticationSpringResourceProvider.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthenticationSpringResourceProvider.java
new file mode 100644
index 00000000..2240b843
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthenticationSpringResourceProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, 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 "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "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.asitplus.eidas.specific.modules.auth.idaustria;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class IdAustriaAuthenticationSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public String getName() {
+ return "Auth. module for ID Austria based authentication";
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ return null;
+
+ }
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ final ClassPathResource idAustriaAuthConfig =
+ new ClassPathResource("/spring/id_austria_auth.beans.xml",
+ IdAustriaAuthenticationSpringResourceProvider.class);
+ final ClassPathResource idAustriaTaskConfig =
+ new ClassPathResource("/spring/id_austria_task.beans.xml",
+ IdAustriaAuthenticationSpringResourceProvider.class);
+
+ return new Resource[] { idAustriaAuthConfig, idAustriaTaskConfig };
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaEidasProxyAuthenticationModulImpl.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaEidasProxyAuthenticationModulImpl.java
new file mode 100644
index 00000000..6f90569c
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaEidasProxyAuthenticationModulImpl.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, 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 "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "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.asitplus.eidas.specific.modules.auth.idaustria;
+
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Authentication-process selection to start ID Austria authentication for eIDAS Proxy-Service requests.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class IdAustriaEidasProxyAuthenticationModulImpl implements AuthModule {
+
+ private static final String ID_AUSTRIA_EIDAS_PROXY_AUTHPROCESS_NAME = "idAustriaForEidasProxyService";
+
+ private int priority = 1;
+
+ @Override
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Sets the priority of this module. Default value is {@code 0}.
+ *
+ * @param priority The priority.
+ */
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.
+ * egovernment.moa.id.process.api.ExecutionContext)
+ */
+ @Override
+ public String selectProcess(ExecutionContext context, IRequest pendingReq) {
+ if (pendingReq instanceof ProxyServicePendingRequest) {
+ log.info("Find eIDAS Proxy-Service request. Starting ID Austria based user authentication ... ");
+ return ID_AUSTRIA_EIDAS_PROXY_AUTHPROCESS_NAME;
+
+ } else {
+ log.trace("No {} request. Ignore it for ID Austria authentication",
+ ProxyServicePendingRequest.class.getName());
+
+ }
+
+ return null;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions()
+ */
+ @Override
+ public String[] getProcessDefinitions() {
+ return new String[] { "classpath:/process/id_austria.Authentication.process.xml" };
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/EidasConnecorUniqueIdAttributeBuilder.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/EidasConnecorUniqueIdAttributeBuilder.java
new file mode 100644
index 00000000..89e06991
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/EidasConnecorUniqueIdAttributeBuilder.java
@@ -0,0 +1,52 @@
+/*
+ * 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.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes;
+
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+
+public class EidasConnecorUniqueIdAttributeBuilder
+ implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
+
+ @Override
+ public String getName() {
+ return EIDAS_CONNECTOR_UNIQUEID_NAME;
+ }
+
+ @Override
+ public <ATT> ATT build(final ISpConfiguration oaParam, final IAuthData authData,
+ final IAttributeGenerator<ATT> g)
+ throws AttributeBuilderException {
+ return g.buildStringAttribute(EIDAS_CONNECTOR_UNIQUEID_FRIENDLY_NAME, EIDAS_CONNECTOR_UNIQUEID_NAME,
+ oaParam.getUniqueIdentifier());
+
+ }
+
+ @Override
+ public <ATT> ATT buildEmpty(final IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(EIDAS_CONNECTOR_UNIQUEID_FRIENDLY_NAME, EIDAS_CONNECTOR_UNIQUEID_NAME);
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/SpRequiredAttributersAttributeBuilder.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/SpRequiredAttributersAttributeBuilder.java
new file mode 100644
index 00000000..61687088
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/SpRequiredAttributersAttributeBuilder.java
@@ -0,0 +1,63 @@
+/*
+ * 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.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class SpRequiredAttributersAttributeBuilder
+ implements IAttributeBuilder, ExtendedPvpAttributeDefinitions {
+
+ @Override
+ public String getName() {
+ return SP_REQUIRED_ATTRIBUTES_NAME;
+ }
+
+ @Override
+ public <ATT> ATT build(final ISpConfiguration oaParam, final IAuthData authData,
+ final IAttributeGenerator<ATT> g)
+ throws AttributeBuilderException {
+ if (oaParam instanceof ServiceProviderConfiguration) {
+ return g.buildStringAttribute(SP_REQUIRED_ATTRIBUTES_FRIENDLY_NAME, SP_REQUIRED_ATTRIBUTES_NAME,
+ StringUtils.join(((ServiceProviderConfiguration)oaParam).getRequestedAttributes(), ","));
+
+ } else {
+ log.warn("Can not build attribute for required IDA attributes, because SP config-implementation does not match.");
+ return null;
+
+ }
+ }
+
+ @Override
+ public <ATT> ATT buildEmpty(final IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(SP_REQUIRED_ATTRIBUTES_FRIENDLY_NAME, SP_REQUIRED_ATTRIBUTES_NAME);
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMessageSource.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMessageSource.java
new file mode 100644
index 00000000..697c4496
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMessageSource.java
@@ -0,0 +1,22 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.config;
+
+import java.util.Arrays;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;
+
+/**
+ * i18n message-source for ID Austria authentication errors.
+ *
+ * @author tlenz
+ *
+ */
+public class IdAustriaAuthMessageSource implements IMessageSourceLocation {
+
+ @Override
+ public List<String> getMessageSourceLocation() {
+ return Arrays.asList("classpath:messages/idaustria_auth_messages");
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMetadataConfiguration.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMetadataConfiguration.java
new file mode 100644
index 00000000..41990363
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMetadataConfiguration.java
@@ -0,0 +1,462 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.config;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.opensaml.saml.saml2.core.Attribute;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.metadata.ContactPerson;
+import org.opensaml.saml.saml2.metadata.Organization;
+import org.opensaml.saml.saml2.metadata.RequestedAttribute;
+import org.opensaml.security.credential.Credential;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Configuration object to generate PVP S-Profile metadata for SAML2 client.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class IdAustriaAuthMetadataConfiguration implements IPvpMetadataBuilderConfiguration {
+
+ private Collection<RequestedAttribute> additionalAttributes = null;
+
+ private final String authUrl;
+ private final IdAustriaAuthCredentialProvider credentialProvider;
+ private final IPvp2BasicConfiguration pvpConfiguration;
+
+ /**
+ * Configuration object to create PVP2 S-Profile metadata information.
+ *
+ * @param authUrl Public URL prefix of the application
+ * @param credentialProvider Credentials used by PVP2 S-Profile end-point
+ * @param pvpConfiguration Basic PVP2 S-Profile end-point configuration
+ */
+ public IdAustriaAuthMetadataConfiguration(String authUrl,
+ IdAustriaAuthCredentialProvider credentialProvider,
+ IPvp2BasicConfiguration pvpConfiguration) {
+ this.authUrl = authUrl;
+ this.credentialProvider = credentialProvider;
+ this.pvpConfiguration = pvpConfiguration;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getMetadataValidUntil()
+ */
+ @Override
+ public int getMetadataValidUntil() {
+ return IdAustriaAuthConstants.METADATA_VALIDUNTIL_IN_HOURS;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * buildEntitiesDescriptorAsRootElement()
+ */
+ @Override
+ public boolean buildEntitiesDescriptorAsRootElement() {
+ return false;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * buildIDPSSODescriptor()
+ */
+ @Override
+ public boolean buildIdpSsoDescriptor() {
+ return false;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * buildSPSSODescriptor()
+ */
+ @Override
+ public boolean buildSpSsoDescriptor() {
+ return true;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getEntityIDPostfix()
+ */
+ @Override
+ public String getEntityID() {
+ return authUrl + IdAustriaAuthConstants.ENDPOINT_METADATA;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getEntityFriendlyName()
+ */
+ @Override
+ public String getEntityFriendlyName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getContactPersonInformation()
+ */
+ @Override
+ public List<ContactPerson> getContactPersonInformation() {
+ try {
+ return pvpConfiguration.getIdpContacts();
+
+ } catch (final EaafException e) {
+ log.warn("Can not load Metadata entry: Contect Person", e);
+ return null;
+
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getOrgansiationInformation()
+ */
+ @Override
+ public Organization getOrgansiationInformation() {
+ try {
+ return pvpConfiguration.getIdpOrganisation();
+
+ } catch (final EaafException e) {
+ log.warn("Can not load Metadata entry: Organisation", e);
+ return null;
+
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getMetadataSigningCredentials()
+ */
+ @Override
+ public EaafX509Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getMetaDataSigningCredential();
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getRequestorResponseSigningCredentials()
+ */
+ @Override
+ public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getMessageSigningCredential();
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getEncryptionCredentials()
+ */
+ @Override
+ public Credential getEncryptionCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getMessageEncryptionCredential();
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getIDPWebSSOPostBindingURL()
+ */
+ @Override
+ public String getIdpWebSsoPostBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getIDPWebSSORedirectBindingURL()
+ */
+ @Override
+ public String getIdpWebSsoRedirectBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getIDPSLOPostBindingURL()
+ */
+ @Override
+ public String getIdpSloPostBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getIDPSLORedirectBindingURL()
+ */
+ @Override
+ public String getIdpSloRedirectBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPAssertionConsumerServicePostBindingURL()
+ */
+ @Override
+ public String getSpAssertionConsumerServicePostBindingUrl() {
+ return authUrl + IdAustriaAuthConstants.ENDPOINT_POST;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPAssertionConsumerServiceRedirectBindingURL()
+ */
+ @Override
+ public String getSpAssertionConsumerServiceRedirectBindingUrl() {
+ return authUrl + IdAustriaAuthConstants.ENDPOINT_REDIRECT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPSLOPostBindingURL()
+ */
+ @Override
+ public String getSpSloPostBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPSLORedirectBindingURL()
+ */
+ @Override
+ public String getSpSloRedirectBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPSLOSOAPBindingURL()
+ */
+ @Override
+ public String getSpSloSoapBindingUrl() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getIDPPossibleAttributes()
+ */
+ @Override
+ public List<Attribute> getIdpPossibleAttributes() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getIDPPossibleNameITTypes()
+ */
+ @Override
+ public List<String> getIdpPossibleNameIdTypes() {
+ return null;
+ }
+
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPRequiredAttributes()
+ */
+ @Override
+ public Collection<RequestedAttribute> getSpRequiredAttributes() {
+ final Map<String, RequestedAttribute> requestedAttributes = new HashMap<>();
+ log.trace("Build required attributes for ID Austria operaton ... ");
+ injectDefinedAttributes(requestedAttributes,
+ IdAustriaAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTES);
+
+
+ if (additionalAttributes != null) {
+ log.trace("Add additional PVP attributes into metadata ... ");
+ for (final RequestedAttribute el : additionalAttributes) {
+ if (requestedAttributes.containsKey(el.getName())) {
+ log.debug("Attribute " + el.getName()
+ + " is already added by default configuration. Overwrite it by user configuration");
+ }
+
+ requestedAttributes.put(el.getName(), el);
+
+ }
+ }
+
+ return requestedAttributes.values();
+
+ }
+
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#
+ * getSPAllowedNameITTypes()
+ */
+ @Override
+ public List<String> getSpAllowedNameIdTypes() {
+ return Arrays.asList(NameIDType.PERSISTENT);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPMetadataBuilderConfiguration#getSPNameForLogging()
+ */
+ @Override
+ public String getSpNameForLogging() {
+ return IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPMetadataBuilderConfiguration#wantAssertionSigned()
+ */
+ @Override
+ public boolean wantAssertionSigned() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPMetadataBuilderConfiguration#wantAuthnRequestSigned()
+ */
+ @Override
+ public boolean wantAuthnRequestSigned() {
+ return true;
+ }
+
+ /**
+ * Add additonal PVP attributes that are required by this deployment.
+ *
+ * @param additionalAttr List of PVP attribute name and isRequired flag
+ */
+ public void setAdditionalRequiredAttributes(List<Pair<String, Boolean>> additionalAttr) {
+ if (additionalAttr != null && !additionalAttr.isEmpty()) {
+ additionalAttributes = new ArrayList<>();
+ for (final Pair<String, Boolean> el : additionalAttr) {
+ final Attribute attributBuilder = PvpAttributeBuilder.buildEmptyAttribute(el.getFirst());
+ if (attributBuilder != null) {
+ additionalAttributes.add(
+ PvpAttributeBuilder.buildReqAttribute(
+ attributBuilder.getName(),
+ attributBuilder.getFriendlyName(),
+ el.getSecond()));
+
+ } else {
+ log.info("NO PVP attribute with name: " + el.getFirst());
+ }
+
+ }
+ }
+ }
+
+ private void injectDefinedAttributes(Map<String, RequestedAttribute> requestedAttributes,
+ List<Triple<String, String, Boolean>> attributes) {
+ for (final Triple<String, String, Boolean> el : attributes) {
+ requestedAttributes.put(el.getFirst(), PvpAttributeBuilder.buildReqAttribute(el.getFirst(), el
+ .getSecond(), el.getThird()));
+
+ }
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthRequestBuilderConfiguration.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthRequestBuilderConfiguration.java
new file mode 100644
index 00000000..52bd1c5f
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthRequestBuilderConfiguration.java
@@ -0,0 +1,307 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.config;
+
+import java.util.List;
+
+import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.w3c.dom.Element;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPvpAuthnRequestBuilderConfiguruation;
+
+/**
+ * ID Austria client-specific implementation of an {@link IPvpAuthnRequestBuilderConfiguruation}.
+ *
+ * @author tlenz
+ *
+ */
+public class IdAustriaAuthRequestBuilderConfiguration implements IPvpAuthnRequestBuilderConfiguruation {
+
+ private boolean isPassive;
+ private String spEntityId;
+ private String qaaLevel;
+ private EntityDescriptor idpEntity;
+ private EaafX509Credential signCred;
+ private String scopeRequesterId;
+ private String providerName;
+ private List<EaafRequestedAttribute> requestedAttributes;
+ private String reqId;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#isPassivRequest()
+ */
+ @Override
+ public Boolean isPassivRequest() {
+ return this.isPassive;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getAssertionConsumerServiceId()
+ */
+ @Override
+ public Integer getAssertionConsumerServiceId() {
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getEntityID()
+ */
+ @Override
+ public String getSpEntityID() {
+ return this.spEntityId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getNameIDPolicy()
+ */
+ @Override
+ public String getNameIdPolicyFormat() {
+ return NameIDType.PERSISTENT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getNameIDPolicy()
+ */
+ @Override
+ public boolean getNameIdPolicyAllowCreation() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getAuthnContextClassRef()
+ */
+ @Override
+ public String getAuthnContextClassRef() {
+ return this.qaaLevel;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getAuthnContextComparison()
+ */
+ @Override
+ public AuthnContextComparisonTypeEnumeration getAuthnContextComparison() {
+ return AuthnContextComparisonTypeEnumeration.MINIMUM;
+ }
+
+ /**
+ * Set isPassive flag in SAML2 request.
+ *
+ * @param isPassive the isPassive to set.
+ */
+ public void setPassive(boolean isPassive) {
+ this.isPassive = isPassive;
+ }
+
+ /**
+ * Set the requester EntityId.
+ *
+ * @param spEntityId EntityId of SP
+ */
+ public void setSpEntityID(String spEntityId) {
+ this.spEntityId = spEntityId;
+ }
+
+ /**
+ * Set required LoA.
+ *
+ * @param loa the LoA to set.
+ */
+ public void setRequestedLoA(String loa) {
+ qaaLevel = loa;
+ }
+
+ /**
+ * Set EntityId of IDP.
+ *
+ * @param idpEntity the idpEntity to set.
+ */
+ public void setIdpEntity(EntityDescriptor idpEntity) {
+ this.idpEntity = idpEntity;
+ }
+
+ /**
+ * Set message signing credentials.
+ *
+ * @param signCred the signCred to set.
+ */
+ public void setSignCred(EaafX509Credential signCred) {
+ this.signCred = signCred;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getAuthnRequestSigningCredential()
+ */
+ @Override
+ public EaafX509Credential getAuthnRequestSigningCredential() {
+ return this.signCred;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getIDPEntityDescriptor()
+ */
+ @Override
+ public EntityDescriptor getIdpEntityDescriptor() {
+ return this.idpEntity;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getSubjectNameID()
+ */
+ @Override
+ public String getSubjectNameID() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getSPNameForLogging()
+ */
+ @Override
+ public String getSpNameForLogging() {
+ return IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getSubjectNameIDFormat()
+ */
+ @Override
+ public String getSubjectNameIdFormat() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getRequestID()
+ */
+ @Override
+ public String getRequestID() {
+ return this.reqId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getSubjectNameIDQualifier()
+ */
+ @Override
+ public String getSubjectNameIdQualifier() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getSubjectConformationMethode()
+ */
+ @Override
+ public String getSubjectConformationMethode() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.
+ * IPVPAuthnRequestBuilderConfiguruation#getSubjectConformationDate()
+ */
+ @Override
+ public Element getSubjectConformationDate() {
+ return null;
+ }
+
+ @Override
+ public List<EaafRequestedAttribute> getRequestedAttributes() {
+ return this.requestedAttributes;
+
+ }
+
+ @Override
+ public String getProviderName() {
+ return this.providerName;
+ }
+
+ @Override
+ public String getScopeRequesterId() {
+ return this.scopeRequesterId;
+ }
+
+ /**
+ * Set the entityId of the SP that requests the proxy for eIDAS authentication.
+ *
+ * @param scopeRequesterId RequestId in SAML2 Proxy extension
+ */
+ public void setScopeRequesterId(String scopeRequesterId) {
+ this.scopeRequesterId = scopeRequesterId;
+ }
+
+ /**
+ * Set a friendlyName for the SP that requests the proxy for eIDAS
+ * authentication.
+ *
+ * @param providerName SAML2 provider-name attribute-value
+ */
+ public void setProviderName(String providerName) {
+ this.providerName = providerName;
+ }
+
+ /**
+ * Set a Set of PVP attributes that a requested by using requested attributes.
+ *
+ * @param requestedAttributes Requested SAML2 attributes
+ */
+ public void setRequestedAttributes(List<EaafRequestedAttribute> requestedAttributes) {
+ this.requestedAttributes = requestedAttributes;
+ }
+
+ /**
+ * Set a RequestId for this Authn. Request.
+ *
+ * @param reqId SAML2 message requestId
+ */
+ public void setRequestId(String reqId) {
+ this.reqId = reqId;
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthMetadataController.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthMetadataController.java
new file mode 100644
index 00000000..ad708d30
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthMetadataController.java
@@ -0,0 +1,150 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.controller;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import com.google.common.net.MediaType;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthMetadataConfiguration;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.http.HttpUtils;
+import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Controller that generates SAML2 metadata for ID Austria authentication client.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+@Controller
+public class IdAustriaAuthMetadataController extends AbstractController {
+
+ private static final String ERROR_CODE_INTERNAL_00 = "eaaf.core.00";
+
+ @Autowired
+ PvpMetadataBuilder metadatabuilder;
+ @Autowired
+ IdAustriaAuthCredentialProvider credentialProvider;
+ @Autowired
+ IPvp2BasicConfiguration pvpConfiguration;
+
+ /**
+ * Default construction with logging.
+ *
+ */
+ public IdAustriaAuthMetadataController() {
+ super();
+ log.debug("Registering servlet " + getClass().getName()
+ + " with mappings '" + IdAustriaAuthConstants.ENDPOINT_METADATA
+ + "'.");
+
+ }
+
+ /**
+ * End-point that produce PVP2 metadata for ID Austria authentication client.
+ *
+ * @param req http Request
+ * @param resp http Response
+ * @throws IOException In case of an I/O error
+ * @throws EaafException In case of a metadata generation error
+ */
+ @RequestMapping(value = IdAustriaAuthConstants.ENDPOINT_METADATA,
+ method = { RequestMethod.GET })
+ public void getSpMetadata(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ EaafException {
+ // check PublicURL prefix
+ try {
+ final String authUrl = getAuthUrlFromHttpContext(req);
+
+ // initialize metadata builder configuration
+ final IdAustriaAuthMetadataConfiguration metadataConfig =
+ new IdAustriaAuthMetadataConfiguration(authUrl, credentialProvider, pvpConfiguration);
+ metadataConfig.setAdditionalRequiredAttributes(getAdditonalRequiredAttributes());
+
+ // build metadata
+ final String xmlMetadata = metadatabuilder.buildPvpMetadata(metadataConfig);
+
+ // write response
+ final byte[] content = xmlMetadata.getBytes("UTF-8");
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentLength(content.length);
+ resp.setContentType(MediaType.XML_UTF_8.toString());
+ resp.getOutputStream().write(content);
+
+ } catch (final Exception e) {
+ log.warn("Build PVP metadata for ID Austria client FAILED.", e);
+ protAuthService.handleErrorNoRedirect(e, req, resp, false);
+
+ }
+
+ }
+
+ private String getAuthUrlFromHttpContext(HttpServletRequest req) throws EaafException {
+ // check if End-Point is valid
+ final String authUrlString = HttpUtils.extractAuthUrlFromRequest(req);
+ URL authReqUrl;
+ try {
+ authReqUrl = new URL(authUrlString);
+
+ } catch (final MalformedURLException e) {
+ log.warn("Requested URL: {} is not a valid URL.", authUrlString);
+ throw new EaafAuthenticationException(ERROR_CODE_INTERNAL_00, new Object[] { authUrlString }, e);
+
+ }
+
+ final String idpAuthUrl = authConfig.validateIdpUrl(authReqUrl);
+ if (idpAuthUrl == null) {
+ log.warn("Requested URL: {} is NOT found in configuration.", authReqUrl);
+ throw new EaafAuthenticationException(ERROR_CODE_INTERNAL_00, new Object[] { authUrlString });
+
+ }
+
+ return idpAuthUrl;
+ }
+
+ private List<Pair<String, Boolean>> getAdditonalRequiredAttributes() {
+ final List<Pair<String, Boolean>> result = new ArrayList<>();
+ // load attributes from configuration
+ final Map<String, String> addReqAttributes = authConfig.getBasicConfigurationWithPrefix(
+ IdAustriaAuthConstants.CONFIG_PROPS_REQUIRED_PVP_ATTRIBUTES_LIST);
+ for (final String el : addReqAttributes.values()) {
+ if (StringUtils.isNotEmpty(el)) {
+ log.trace("Parse additional attr. definition: " + el);
+ final List<String> attr = KeyValueUtils.getListOfCsvValues(el.trim());
+ if (attr.size() == 2) {
+ result.add(Pair.newInstance(attr.get(0), Boolean.parseBoolean(attr.get(1))));
+
+ } else {
+ log.info("IGNORE additional attr. definition: " + el
+ + " Reason: Format not valid");
+ }
+ }
+ }
+
+ return result;
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthSignalController.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthSignalController.java
new file mode 100644
index 00000000..2e7868fd
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthSignalController.java
@@ -0,0 +1,94 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.controller;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractProcessEngineSignalController;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Controller that receives the response from ID Austria system.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+@Controller
+public class IdAustriaAuthSignalController extends AbstractProcessEngineSignalController {
+
+ public static final String HTTP_PARAM_RELAYSTATE = "RelayState";
+
+ /**
+ * Default constructor with logging.
+ *
+ */
+ public IdAustriaAuthSignalController() {
+ super();
+ log.debug("Registering servlet " + getClass().getName()
+ + " with mappings '" + IdAustriaAuthConstants.ENDPOINT_POST
+ + "' and '" + IdAustriaAuthConstants.ENDPOINT_REDIRECT + "'.");
+
+ }
+
+ /**
+ * HTTP end-point for incoming SAML2 Respone from ID Austrian System.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ * @throws IOException In case of a HTTP communication error
+ * @throws EaafException In case of a state-validation problem
+ */
+ @RequestMapping(value = { IdAustriaAuthConstants.ENDPOINT_POST,
+ IdAustriaAuthConstants.ENDPOINT_REDIRECT },
+ method = { RequestMethod.POST, RequestMethod.GET })
+ public void performEidasAuthentication(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException, EaafException {
+ signalProcessManagement(req, resp);
+
+ }
+
+ /**
+ * Read the PendingRequestId from SAML2 RelayState parameter.
+ */
+ @Override
+ public String getPendingRequestId(HttpServletRequest request) {
+ String relayState = StringEscapeUtils.escapeHtml4(request.getParameter(HTTP_PARAM_RELAYSTATE));
+ if (StringUtils.isNotEmpty(relayState)) {
+ try {
+ String pendingReqId = transactionStorage.get(relayState, String.class);
+ if (StringUtils.isNotEmpty(pendingReqId)) {
+
+ return pendingReqId;
+
+ } else {
+ log.info("SAML2 RelayState from request is unknown. Can NOT restore session ... ");
+
+ }
+
+ } catch (EaafException e) {
+ log.error("Can NOT map SAML2 RelayState to pendingRequestId", e);
+
+ } finally {
+ transactionStorage.remove(relayState);
+
+ }
+
+ } else {
+ log.info("No SAML2 relaystate. Can NOT restore session ... ");
+
+ }
+
+ return null;
+
+ }
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java
new file mode 100644
index 00000000..e59b0671
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java
@@ -0,0 +1,370 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.tasks;
+
+import java.io.IOException;
+import java.util.Set;
+
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.core.StatusCode;
+import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.Utils;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+import at.gv.egiz.eaaf.modules.pvp2.api.binding.IDecoder;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+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.InboundMessage;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AssertionValidationExeption;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnResponseValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.sp.impl.utils.AssertionAttributeExtractor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * ID Austria authentication task that receives the SAML2 response from ID
+ * Austria system.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class ReceiveFromIdAustriaSystemTask extends AbstractAuthServletTask {
+
+ private static final String ERROR_PVP_03 = "sp.pvp2.03";
+ private static final String ERROR_PVP_05 = "sp.pvp2.05";
+ private static final String ERROR_PVP_06 = "sp.pvp2.06";
+ private static final String ERROR_PVP_08 = "sp.pvp2.08";
+ private static final String ERROR_PVP_10 = "sp.pvp2.10";
+ private static final String ERROR_PVP_11 = "sp.pvp2.11";
+ private static final String ERROR_PVP_12 = "sp.pvp2.12";
+
+ private static final String ERROR_MSG_00 =
+ "Receive INVALID PVP Response from federated IDP";
+ private static final String ERROR_MSG_01 =
+ "Processing PVP response from 'ms-specific eIDAS node' FAILED.";
+ private static final String ERROR_MSG_02 =
+ "PVP response decrytion FAILED. No credential found.";
+ private static final String ERROR_MSG_03 =
+ "PVP response validation FAILED.";
+
+ @Autowired
+ private SamlVerificationEngine samlVerificationEngine;
+ @Autowired
+ private IdAustriaAuthCredentialProvider credentialProvider;
+ @Autowired(required = true)
+ IdAustriaAuthMetadataProvider metadataProvider;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask#execute(at.gv.
+ * egovernment.moa.id.process.api.ExecutionContext,
+ * javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request,
+ HttpServletResponse response)
+ throws TaskExecutionException {
+ InboundMessage msg = null;
+
+ try {
+
+ IDecoder decoder = null;
+ EaafUriCompare comperator = null;
+ // select Response Binding
+ if (request.getMethod().equalsIgnoreCase("POST")) {
+ decoder = new PostBinding();
+ comperator = new EaafUriCompare(pendingReq.getAuthUrl() + IdAustriaAuthConstants.ENDPOINT_POST);
+ log.trace("Receive PVP Response from 'ID Austria', by using POST-Binding.");
+
+ } else if (request.getMethod().equalsIgnoreCase("GET")) {
+ decoder = new RedirectBinding();
+ comperator = new EaafUriCompare(pendingReq.getAuthUrl()
+ + IdAustriaAuthConstants.ENDPOINT_REDIRECT);
+ log.trace("Receive PVP Response from 'ID Austria', by using Redirect-Binding.");
+
+ } else {
+ log.warn("Receive PVP Response, but Binding ("
+ + request.getMethod() + ") is not supported.");
+ throw new AuthnResponseValidationException(ERROR_PVP_03, new Object[] {
+ IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING });
+
+ }
+
+ // decode PVP response object
+ msg = (InboundMessage) decoder.decode(
+ request, response, metadataProvider, IDPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comperator);
+
+ // validate response signature
+ if (!msg.isVerified()) {
+ samlVerificationEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ msg.setVerified(true);
+
+ }
+
+ // validate assertion
+ final Pair<PvpSProfileResponse, Boolean> processedMsg =
+ preProcessAuthResponse((PvpSProfileResponse) msg);
+
+ // check if SAML2 response contains user-stop decision
+ if (processedMsg.getSecond()) {
+ stopProcessFromUserDecision(executionContext, request, response);
+
+ } else {
+ // validate entityId of response
+ final String idAustriaEntityID =
+ Utils.getIdAustriaEntityId(pendingReq.getServiceProviderConfiguration(), authConfig);
+ final String respEntityId = msg.getEntityID();
+ if (!idAustriaEntityID.equals(respEntityId)) {
+ log.warn("Response Issuer is not a 'ID Austria System'. Stopping eIDAS authentication ...");
+ throw new AuthnResponseValidationException(ERROR_PVP_08,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING,
+ msg.getEntityID() });
+
+ }
+
+ // initialize Attribute extractor
+ final AssertionAttributeExtractor extractor =
+ new AssertionAttributeExtractor(processedMsg.getFirst().getResponse());
+
+ getAuthDataFromInterfederation(extractor);
+
+ // set NeedConsent to false, because user gives consont during authentication
+ pendingReq.setNeedUserConsent(false);
+
+ // store pending-request
+ requestStoreage.storePendingRequest(pendingReq);
+
+ // write log entries
+ // revisionsLogger.logEvent(pendingReq,
+ // EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_MDS_VALID);
+ log.info("Receive a valid assertion from IDP " + msg.getEntityID());
+
+ }
+
+ } catch (final AuthnResponseValidationException e) {
+ throw new TaskExecutionException(pendingReq, ERROR_MSG_03, e);
+
+ } catch (MessageDecodingException | SecurityException | SamlSigningException e) {
+ final String samlRequest = request.getParameter("SAMLRequest");
+ log.debug("Receive INVALID PVP Response from 'ID Austria System': {}",
+ samlRequest, null, e);
+ throw new TaskExecutionException(pendingReq, ERROR_MSG_00,
+ new AuthnResponseValidationException(ERROR_PVP_11,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING }, e));
+
+ } catch (IOException | MarshallingException | TransformerException e) {
+ log.debug("Processing PVP response from 'ID Austria System' FAILED.", e);
+ throw new TaskExecutionException(pendingReq, ERROR_MSG_01,
+ new AuthnResponseValidationException(ERROR_PVP_12,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage() },
+ e));
+
+ } catch (final CredentialsNotAvailableException e) {
+ log.debug("PVP response decrytion FAILED. No credential found.", e);
+ throw new TaskExecutionException(pendingReq, ERROR_MSG_02,
+ new AuthnResponseValidationException(ERROR_PVP_10,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING }, e));
+
+ } catch (final Exception e) {
+ log.debug("PVP response validation FAILED. Msg:" + e.getMessage(), e);
+ throw new TaskExecutionException(pendingReq, ERROR_MSG_03,
+ new AuthnResponseValidationException(ERROR_PVP_12,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage() }, e));
+
+ }
+
+ }
+
+ private void getAuthDataFromInterfederation(AssertionAttributeExtractor extractor)
+ throws EaafBuilderException, ConfigurationException {
+
+ final Set<String> requiredEidasNodeAttributes =
+ IdAustriaAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES;
+ try {
+ // check if all attributes are include
+ if (!extractor.containsAllRequiredAttributes(requiredEidasNodeAttributes)) {
+ log.warn("PVP Response from 'ID Austria System' contains not all requested attributes.");
+ throw new AssertionValidationExeption(ERROR_PVP_06, new Object[] {
+ IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING });
+
+ }
+
+ // copy attributes into MOASession
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(
+ AuthProcessDataWrapper.class);
+
+ // validate response attributes
+ validateResponseAttributes(extractor);
+
+ // inject all attributes into session
+ final Set<String> includedAttrNames = extractor.getAllIncludeAttributeNames();
+ for (final String attrName : includedAttrNames) {
+ injectAuthInfosIntoSession(session, attrName, extractor.getSingleAttributeValue(attrName));
+
+ }
+
+ // set foreigner flag
+ session.setForeigner(false);
+
+ // mark it as ID Austria process, because we have no baseId
+ session.setEidProcess(true);
+
+ // set IssuerInstant from Assertion
+ session.setIssueInstant(extractor.getAssertionIssuingDate());
+
+ // set mandate flag
+ session.setUseMandates(checkIfMandateInformationIsAvailable(extractor));
+
+
+ } catch (final EaafException | IOException e) {
+ throw new EaafBuilderException(ERROR_PVP_06, null, e.getMessage(), e);
+
+ }
+ }
+
+
+ /**
+ * Check if mandate information is available.
+ *
+ * @param extractor Assertion from ID Austria system.
+ * @return <code>true</code> if mandate was used, otherwise <code>false</code>
+ */
+ private boolean checkIfMandateInformationIsAvailable(AssertionAttributeExtractor extractor) {
+ boolean isMandateIncluded = extractor.containsAttribute(PvpAttributeDefinitions.MANDATE_TYPE_NAME);
+ log.debug("Response from ID-Austria system contains {} mandate information. Switch to {} ... ",
+ isMandateIncluded ? "" : "no", isMandateIncluded ? "mandate mode" : "normal mode");
+ return isMandateIncluded;
+
+ }
+
+ private void validateResponseAttributes(AssertionAttributeExtractor extractor)
+ throws EaafAuthenticationException {
+ final String bpkTarget = extractor.getSingleAttributeValue(
+ PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME);
+ final String spTarget = pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier();
+ if (StringUtils.isNotEmpty(bpkTarget) && bpkTarget.equals(spTarget)) {
+ log.debug("Find attr: {} that matches to requested bPK target. bPK should be valid",
+ PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME);
+
+ } else {
+ log.trace("Find not attr: {}. Validation bPK attribute ... ",
+ PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME);
+ final String bpk = extractor.getSingleAttributeValue(PvpAttributeDefinitions.BPK_NAME);
+ final String[] split = bpk.split(":", 2);
+ if (split.length == 2) {
+ if (!spTarget.endsWith(split[0])) {
+ log.error("bPK from response: {} does not match to SP target: {}", bpk, spTarget);
+ throw new EaafAuthenticationException(IdAustriaAuthConstants.ERRORTYPE_06, null);
+
+ } else {
+ log.trace("Prefix of PVP bPK attribte matches to SP configuration. bPK looks valid");
+
+ }
+
+ } else {
+ log.warn("Find suspect bPK that has no prefix. Use it as it is ... ");
+
+ }
+ }
+ }
+
+ private void injectAuthInfosIntoSession(AuthProcessDataWrapper session,
+ String attrName, String attrValue) throws EaafStorageException, IOException {
+ log.trace("Inject attribute: {} with value: {} into AuthSession", attrName, attrValue);
+ log.debug("Inject attribute: {} into AuthSession", attrName);
+ session.setGenericDataToSession(attrName, attrValue);
+
+ }
+
+ private Pair<PvpSProfileResponse, Boolean> preProcessAuthResponse(PvpSProfileResponse msg)
+ throws IOException, MarshallingException, TransformerException,
+ CredentialsNotAvailableException, AuthnResponseValidationException, SamlAssertionValidationExeption {
+ log.debug("Start PVP-2x assertion processing... ");
+ final Response samlResp = (Response) msg.getResponse();
+
+ // check SAML2 response status-code
+ if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS)) {
+ // validate PVP 2.1 assertion
+ samlVerificationEngine.validateAssertion(samlResp,
+ credentialProvider.getMessageEncryptionCredential(),
+ pendingReq.getAuthUrl() + IdAustriaAuthConstants.ENDPOINT_METADATA,
+ IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING);
+
+ msg.setSamlMessage(Saml2Utils.asDomDocument(samlResp).getDocumentElement());
+ // revisionsLogger.logEvent(pendingReq,
+ // EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_RECEIVED,
+ // samlResp.getID());
+ return Pair.newInstance(msg, false);
+
+ } else {
+ log.info("Receive StatusCode " + samlResp.getStatus().getStatusCode().getValue()
+ + " from 'ms-specific eIDAS node'.");
+ final StatusCode subStatusCode = getSubStatusCode(samlResp);
+ if (subStatusCode != null
+ && IdAustriaAuthConstants.SAML2_STATUSCODE_USERSTOP.equals(subStatusCode.getValue())) {
+ log.info("Find 'User-Stop operation' in SAML2 response. Stopping authentication process ... ");
+ return Pair.newInstance(msg, true);
+
+ }
+
+ // revisionsLogger.logEvent(pendingReq,
+ // EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_RECEIVED_ERROR);
+ throw new AuthnResponseValidationException(ERROR_PVP_05,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING,
+ samlResp.getIssuer().getValue(),
+ samlResp.getStatus().getStatusCode().getValue(),
+ samlResp.getStatus().getStatusMessage().getValue() });
+
+ }
+
+ }
+
+ /**
+ * Get SAML2 Sub-StatusCode if not <code>null</code>.
+ *
+ * @param samlResp SAML2 response
+ * @return Sub-StatusCode or <code>null</code> if it's not set
+ */
+ private StatusCode getSubStatusCode(Response samlResp) {
+ if (samlResp.getStatus().getStatusCode().getStatusCode() != null
+ && StringUtils.isNotEmpty(samlResp.getStatus().getStatusCode().getStatusCode().getValue())) {
+ return samlResp.getStatus().getStatusCode().getStatusCode();
+
+ }
+ return null;
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
new file mode 100644
index 00000000..bbe9b45f
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
@@ -0,0 +1,211 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.tasks;
+
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.messaging.encoder.MessageEncodingException;
+import org.opensaml.saml.saml2.core.Attribute;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthRequestBuilderConfiguration;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.Utils;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException;
+import at.gv.egiz.eaaf.modules.pvp2.sp.impl.PvpAuthnRequestBuilder;
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+import net.shibboleth.utilities.java.support.security.impl.SecureRandomIdentifierGenerationStrategy;
+
+/**
+ * eIDAS Authentication task that generates PVP2 S-Profile request to central
+ * Austrian MS-Connector.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class RequestIdAustriaSystemTask extends AbstractAuthServletTask {
+
+ private static final String ERROR_PVP_02 = "sp.pvp2.02";
+ private static final String ERROR_PVP_13 = "sp.pvp2.13";
+
+ private static final String ERROR_MSG_1 =
+ "Requested 'ms-specific eIDAS node' {0} has no valid metadata or metadata is not found";
+ private static final String ERROR_MSG_4 =
+ "Build PVP2.1 AuthnRequest to connect 'ms-specific eIDAS node' FAILED.";
+
+ @Autowired PvpAuthnRequestBuilder authnReqBuilder;
+ @Autowired IdAustriaAuthCredentialProvider credential;
+ @Autowired IdAustriaAuthMetadataProvider metadataService;
+ @Autowired ITransactionStorage transactionStorage;
+
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request,
+ HttpServletResponse response)
+ throws TaskExecutionException {
+ try {
+ //revisionsLogger.logEvent(pendingReq, EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_SELECTED);
+
+ // get entityID for central ID Austria system
+ final String idAustriaEntityID =
+ Utils.getIdAustriaEntityId(pendingReq.getServiceProviderConfiguration(), authConfig);
+ if (StringUtils.isEmpty(idAustriaEntityID)) {
+ log.info("ID Austria authentication not possible -> NO EntityID for central central ID Austria System FOUND!");
+ throw new EaafConfigurationException(IdAustriaAuthConstants.ERRORTYPE_00,
+ new Object[] { IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID });
+
+ }
+
+ // load IDP SAML2 entitydescriptor
+ final EntityDescriptor entityDesc = metadataService.getEntityDescriptor(idAustriaEntityID);
+ if (entityDesc == null) {
+ throw new EaafConfigurationException(IdAustriaAuthConstants.ERRORTYPE_05,
+ new Object[] { MessageFormat.format(ERROR_MSG_1, idAustriaEntityID) });
+
+ }
+
+ // setup AuthnRequestBuilder configuration
+ final IdAustriaAuthRequestBuilderConfiguration authnReqConfig =
+ new IdAustriaAuthRequestBuilderConfiguration();
+ final SecureRandomIdentifierGenerationStrategy gen =
+ new SecureRandomIdentifierGenerationStrategy();
+
+ // set basic infos
+ authnReqConfig.setRequestId(gen.generateIdentifier());
+ authnReqConfig.setIdpEntity(entityDesc);
+ authnReqConfig.setPassive(false);
+ authnReqConfig.setSignCred(credential.getMessageSigningCredential());
+ authnReqConfig.setSpEntityID(pendingReq.getAuthUrl() + IdAustriaAuthConstants.ENDPOINT_METADATA);
+
+ // set eIDAS Proxy-Service specific information for ID Austria system
+ authnReqConfig.setRequestedAttributes(buildRequestedAttributes(pendingReq));
+
+
+ /*build relayState for session synchronization, because SAML2 only allows RelayState with 80 characters
+ * but encrypted PendingRequestId is much longer.
+ */
+ String relayState = Random.nextProcessReferenceValue();
+ transactionStorage.put(relayState, pendingReq.getPendingRequestId(), -1);
+
+ // build and transmit AuthnRequest
+ authnReqBuilder.buildAuthnRequest(pendingReq, authnReqConfig, relayState, response);
+
+ //revisionsLogger.logEvent(pendingReq,
+ // EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_REQUESTED,
+ // authnReqConfig.getRequestID());
+
+ } catch (final EaafException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (final ResolverException e) {
+ throw new TaskExecutionException(pendingReq,
+ ERROR_MSG_4,
+ new AuthnRequestBuildException(ERROR_PVP_02,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING }, e));
+
+ } catch (MessageEncodingException | NoSuchAlgorithmException | SecurityException e) {
+ throw new TaskExecutionException(pendingReq,
+ e.getMessage(),
+ new AuthnRequestBuildException(ERROR_PVP_13,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING }, e));
+
+ } catch (final Exception e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+ }
+
+ private String selectHighestLoa(List<String> requiredLoA) {
+ //TODO: implement LoA selection
+ return requiredLoA.get(0);
+
+ }
+
+ private List<EaafRequestedAttribute> buildRequestedAttributes(IRequest pendingReq) {
+ final List<EaafRequestedAttribute> attributs = new ArrayList<>();
+
+ //build attribute that contains the unique identifier of the eIDAS-Connector
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.EIDAS_CONNECTOR_UNIQUEID_NAME,
+ pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
+
+ // build EID sector for identification attribute
+ injectAttribute(attributs, PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME,
+ pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier());
+
+ // set requested LoA as attribute
+ injectAttribute(attributs, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ selectHighestLoa(pendingReq.getServiceProviderConfiguration().getRequiredLoA()));
+
+ // set list of IDA attributes as attribute
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_REQUIRED_ATTRIBUTES_NAME,
+ StringUtils.join(
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getRequestedAttributes(),
+ ","));
+
+ //set ProviderName if available
+ String providerName = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getProviderName();
+ if (StringUtils.isNotEmpty(providerName)) {
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_FRIENDLYNAME_NAME, providerName);
+
+ }
+
+ //set ProviderName if available
+ String requesterId = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getRequesterId();
+ if (StringUtils.isNotEmpty(requesterId)) {
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_UNIQUEID_NAME, requesterId);
+
+ }
+
+ //set mandate profiles
+ List<String> mandateProfiles =
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getMandateProfiles();
+ if (mandateProfiles != null && !mandateProfiles.isEmpty()) {
+ log.debug("Set mandate-profiles attribute into ID-Austria request");
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_USED_MANDATE_PROFILES_NAME,
+ StringUtils.join(mandateProfiles, ","));
+
+ }
+
+ // inject mandate mode attribute
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_USED_MANDATE_TYPE_NAME,
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getMandateMode().getMode());
+
+
+ return attributs;
+ }
+
+ private void injectAttribute(List<EaafRequestedAttribute> attributs, String attributeName, String attributeValue) {
+ final Attribute requesterIdAttr = PvpAttributeBuilder.buildEmptyAttribute(attributeName);
+ final EaafRequestedAttribute requesterIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
+ requesterIdAttr,
+ true,
+ attributeValue);
+ attributs.add(requesterIdReqAttr);
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthCredentialProvider.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthCredentialProvider.java
new file mode 100644
index 00000000..7da306b5
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthCredentialProvider.java
@@ -0,0 +1,130 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+
+/**
+ * Credential provider for ID Austria PVP S-Profile client.
+ *
+ * @author tlenz
+ *
+ */
+public class IdAustriaAuthCredentialProvider extends AbstractCredentialProvider {
+
+ @Autowired
+ IConfiguration authConfig;
+
+
+ @Override
+ public KeyStoreConfiguration getBasicKeyStoreConfig() throws EaafConfigurationException {
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setFriendlyName(IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING);
+ keyStoreConfig.setKeyStoreType(
+ authConfig.getBasicConfiguration(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_TYPE,
+ KeyStoreType.PKCS12.getKeyStoreType()));
+ keyStoreConfig.setKeyStoreName(
+ authConfig.getBasicConfiguration(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_NAME));
+ keyStoreConfig.setSoftKeyStoreFilePath(getKeyStoreFilePath());
+ keyStoreConfig.setSoftKeyStorePassword(
+ authConfig.getBasicConfiguration(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTOREPASSWORD));
+
+ return keyStoreConfig;
+
+ }
+
+ private String getKeyStoreFilePath() throws EaafConfigurationException {
+ final String path = authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_PATH);
+ if (path == null) {
+ throw new EaafConfigurationException(IdAustriaAuthConstants.ERRORTYPE_00,
+ new Object[] { IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_PATH });
+
+ }
+ return path;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#
+ * getMetadataKeyAlias()
+ */
+ @Override
+ public String getMetadataKeyAlias() {
+ return authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#
+ * getMetadataKeyPassword()
+ */
+ @Override
+ public String getMetadataKeyPassword() {
+ return authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#
+ * getSignatureKeyAlias()
+ */
+ @Override
+ public String getSignatureKeyAlias() {
+ return authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#
+ * getSignatureKeyPassword()
+ */
+ @Override
+ public String getSignatureKeyPassword() {
+ return authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#
+ * getEncryptionKeyAlias()
+ */
+ @Override
+ public String getEncryptionKeyAlias() {
+ return authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#
+ * getEncryptionKeyPassword()
+ */
+ @Override
+ public String getEncryptionKeyPassword() {
+ return authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD);
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthMetadataProvider.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthMetadataProvider.java
new file mode 100644
index 00000000..72c52488
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthMetadataProvider.java
@@ -0,0 +1,168 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.utils;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.cert.CertificateException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SimpleMetadataSignatureVerificationFilter;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * SAML2 metadata-provider implementation for ID Austria client.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class IdAustriaAuthMetadataProvider extends AbstractChainingMetadataProvider {
+
+ private static final String FRIENDLYNAME_METADATA_TRUSTSTORE = "'ID Austria client-metadata truststore'";
+ private static final String PROVIDER_ID_PATTERN = "ID Austria resolver: {0}";
+ public static final String PROVIDER_ID = "ID Austria_client metadata provider'";
+
+ @Autowired
+ private IConfiguration basicConfig;
+
+ @Autowired
+ private PvpMetadataResolverFactory metadataProviderFactory;
+ @Autowired
+ private IHttpClientFactory httpClientFactory;
+
+ @Autowired
+ private EaafKeyStoreFactory keyStoreFactory;
+
+ private Pair<KeyStore, Provider> metadataSigningTrustStore;
+
+ @Override
+ protected String getMetadataUrl(String entityId) throws EaafConfigurationException {
+ log.trace("ID Austria uses SAML2 well-known location approach. EntityId is Metadata-URL");
+ return entityId;
+
+ }
+
+ @Override
+ protected MetadataResolver createNewMetadataProvider(String entityId) throws EaafConfigurationException,
+ IOException, CertificateException {
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ metadataSigningTrustStore.getFirst(), entityId));
+
+ final MetadataFilterChain filter = new MetadataFilterChain();
+ filter.setFilters(filterList);
+
+ try {
+ return metadataProviderFactory.createMetadataProvider(getMetadataUrl(entityId),
+ filter,
+ MessageFormat.format(PROVIDER_ID_PATTERN, entityId),
+ httpClientFactory.getHttpClient());
+
+ } catch (final Pvp2MetadataException e) {
+ log.info("Can NOT build metadata provider for entityId: {}", entityId);
+ throw new EaafConfigurationException(IdAustriaAuthConstants.ERRORTYPE_04,
+ new Object[] { entityId, e.getMessage() }, e);
+
+ }
+ }
+
+ @Override
+ protected List<String> getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException {
+ return Collections.emptyList();
+
+ }
+
+ @Override
+ protected String getMetadataProviderId() {
+ return PROVIDER_ID;
+
+ }
+
+ @Override
+ public void runGarbageCollector() {
+ log.trace("Garbage collection is NOT supported by: {}", getId());
+ }
+
+ @Override
+ public void doDestroy() {
+ super.fullyDestroy();
+
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafException {
+ // initialize truststore to validate metadata signing certificates
+ initializeTrustStore();
+
+ // load metadata with metadataURL, as backup
+ initializeFileSystemMetadata();
+
+ }
+
+ private void initializeFileSystemMetadata() {
+ try {
+ final String metadataUrl = basicConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_METADATAURL);
+ if (StringUtils.isNotEmpty(metadataUrl)) {
+ log.info("Use not recommended metadata-provider initialization!"
+ + " SAML2 'Well-Known-Location' is the preferred methode.");
+ log.info("Initialize 'ID Austria' metadata-provider with URL: {}", metadataUrl);
+
+ addMetadataResolverIntoChain(createNewMetadataProvider(metadataUrl));
+ }
+
+ } catch (final EaafConfigurationException | CertificateException | IOException e) {
+ log.warn("Can NOT inject static eIDAS Node metadata-soure.", e);
+ log.warn("Communication with ID Austria can be FAIL.");
+
+ }
+ }
+
+ private void initializeTrustStore() throws EaafException {
+ // set configuration
+ final KeyStoreConfiguration trustStoreConfig = new KeyStoreConfiguration();
+ trustStoreConfig.setFriendlyName(FRIENDLYNAME_METADATA_TRUSTSTORE);
+ trustStoreConfig.setKeyStoreType(basicConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_TRUSTSTORE_TYPE,
+ KeyStoreType.JKS.getKeyStoreType()));
+ trustStoreConfig.setKeyStoreName(basicConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_TRUSTSTORE_NAME));
+ trustStoreConfig.setSoftKeyStoreFilePath(basicConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_TRUSTSTORE_PATH));
+ trustStoreConfig.setSoftKeyStorePassword(basicConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_TRUSTSTORE_PASSWORD));
+
+ // validate configuration
+ trustStoreConfig.validate();
+
+ // open new TrustStore
+ metadataSigningTrustStore = keyStoreFactory.buildNewKeyStore(trustStoreConfig);
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/Utils.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/Utils.java
new file mode 100644
index 00000000..1de6c33f
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/Utils.java
@@ -0,0 +1,44 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.utils;
+
+import javax.annotation.Nullable;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+
+public class Utils {
+
+ /**
+ * Get the EntityId of the ID Austria system that
+ * should be used in this process.
+ *
+ * @param spConfiguration Service-Provider configuration that can include
+ * {@linkplain IdAustriaAuthConstants.CONFIG_PROPS_APPSPECIFIC_IDAUSTRIA_NODE_URL}
+ * @param authConfig Basic application configuration that include
+ * {@linkplain IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID}
+ * @return EntityId, or <code>null</code> if no EntityId was found in configuration
+ */
+ @Nullable
+ public static String getIdAustriaEntityId(
+ ISpConfiguration spConfiguration, IConfiguration authConfig) {
+ // load from service-provider configuration
+ String msNodeEntityID = spConfiguration.getConfigurationValue(
+ IdAustriaAuthConstants.CONFIG_PROPS_APPSPECIFIC_IDAUSTRIA_NODE_URL);
+
+ if (StringUtils.isEmpty(msNodeEntityID)) {
+ msNodeEntityID = authConfig.getBasicConfiguration(
+ IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID);
+
+ }
+
+ return msNodeEntityID;
+ }
+
+ private Utils() {
+ //hide constructor of private class
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
new file mode 100644
index 00000000..6bf41f6f
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
@@ -0,0 +1 @@
+at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthenticationSpringResourceProvider \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder b/modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder
new file mode 100644
index 00000000..3b20d687
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder
@@ -0,0 +1,2 @@
+at.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes.EidasConnecorUniqueIdAttributeBuilder
+at.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes.SpRequiredAttributersAttributeBuilder
diff --git a/modules/authmodule_id-austria/src/main/resources/messages/idaustria_auth_messages.properties b/modules/authmodule_id-austria/src/main/resources/messages/idaustria_auth_messages.properties
new file mode 100644
index 00000000..6de6e0dc
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/resources/messages/idaustria_auth_messages.properties
@@ -0,0 +1,10 @@
+module.idaustria.00=ID Austria authentication-module has an error in configuration. Missing: {0}
+module.idaustria.01=ID Austria authentication-module has an error in configuration: {0}. Reason: {1}
+module.idaustria.02=ID Austria authentication-module has an error in configuration. Reason: {0}
+module.idaustria.03=ID Austria authentication-module has a general error during request pre-processing. Reason: {0}
+module.idaustria.04=ID Austria authentication-module has a general error during response post-processing.
+module.idaustria.05=ID Austria authentication-module can not initialize SAML2 metadata provider for entityId: {0}. Reason: {1}
+module.idaustria.06=ID Austria authentication-module receives an invalid eIDAS bPK, which does NOT match to country-code of eIDAS Proxy-Service
+
+module.idaustria.98=ID Austria authentication-module has an internal error. Reason: {0}
+module.idaustria.99=ID Austria authentication-module has an generic internal error. \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml b/modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml
new file mode 100644
index 00000000..e8a83e68
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pd:ProcessDefinition id="idAustriaForEidasProxyService"
+ xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1">
+
+ <pd:Task id="createAuthnRequestTask" class="createIdAustriaAuthnRequestTask" />
+ <pd:Task id="receiveAuthnResponseTask" class="receiveIdAustriaAuthnResponseTask" async="true" />
+ <pd:Task id="finalizeAuthentication" class="FinalizeAuthenticationTask" />
+
+ <pd:StartEvent id="start" />
+
+ <pd:Transition from="start" to="createAuthnRequestTask" />
+ <pd:Transition from="createAuthnRequestTask" to="receiveAuthnResponseTask" />
+ <pd:Transition from="receiveAuthnResponseTask" to="finalizeAuthentication" />
+ <pd:Transition from="finalizeAuthentication" to="end" />
+
+ <pd:EndEvent id="end" />
+
+</pd:ProcessDefinition>
diff --git a/modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml b/modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml
new file mode 100644
index 00000000..d2d16bf9
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml
@@ -0,0 +1,36 @@
+<?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">
+
+ <context:annotation-config />
+
+ <bean id="idAustriaEidasProxyAuthModule"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaEidasProxyAuthenticationModulImpl" />
+
+ <bean id="eiAustriaAuthMessageSource"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthMessageSource" />
+
+ <bean id="idAustriaAuthCredentialProvider"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider" />
+
+ <bean id="idAustriaAuthMetadataController"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.controller.IdAustriaAuthMetadataController" />
+
+ <bean id="idAustriaAuthSignalController"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.controller.IdAustriaAuthSignalController" />
+
+ <bean id="idAustriaAuthMetadataProvider"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider" />
+
+ <!-- bean id="eidasAuthHealthCheck"
+ class="at.gv.egiz.eid.authhandler.modules.auth.eidas.utils.EidasCentralAuthHealthCheck" /-->
+
+
+</beans> \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml b/modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml
new file mode 100644
index 00000000..9da9145d
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml
@@ -0,0 +1,23 @@
+<?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">
+
+ <context:annotation-config />
+
+ <!-- eIDAS Authentication Process Tasks -->
+ <bean id="createIdAustriaAuthnRequestTask"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.tasks.RequestIdAustriaSystemTask"
+ scope="prototype" />
+
+ <bean id="receiveIdAustriaAuthnResponseTask"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.tasks.ReceiveFromIdAustriaSystemTask"
+ scope="prototype" />
+
+</beans> \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaAuthSpringResourceProviderTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaAuthSpringResourceProviderTest.java
new file mode 100644
index 00000000..478a3ad4
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaAuthSpringResourceProviderTest.java
@@ -0,0 +1,56 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.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.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthenticationSpringResourceProvider;
+import at.gv.egiz.eaaf.core.test.TestConstants;
+
+
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class IdAustriaAuthSpringResourceProviderTest {
+
+ @Test
+ public void testSpringConfig() {
+ final IdAustriaAuthenticationSpringResourceProvider test =
+ new IdAustriaAuthenticationSpringResourceProvider();
+ 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",
+ IdAustriaAuthenticationSpringResourceProvider.class.getName(), spiFile);
+
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found");
+
+ }
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaEidasProxyAuthenticationModulImplTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaEidasProxyAuthenticationModulImplTest.java
new file mode 100644
index 00000000..5a4c8b7e
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/IdAustriaEidasProxyAuthenticationModulImplTest.java
@@ -0,0 +1,102 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaEidasProxyAuthenticationModulImpl;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.ModuleRegistration;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyConfiguration;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummySpConfiguration;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml"})
+@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
+public class IdAustriaEidasProxyAuthenticationModulImplTest {
+
+ @Autowired ModuleRegistration moduleReg;
+ @Autowired ResourceLoader loader;
+ @Autowired ProcessEngine processEngine;
+
+
+ private final ExecutionContext executionContext = new ExecutionContextImpl();
+ private DummySpConfiguration oaParam;
+ private IdAustriaEidasProxyAuthenticationModulImpl authProcess =
+ new IdAustriaEidasProxyAuthenticationModulImpl();
+
+
+ /**
+ * jUnit test set-up.
+ *
+ */
+ @Before
+ public void initialize() {
+ Map<String, String> configMap = new HashMap<String, String>();
+ configMap.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "http://test.com/test");
+ IConfiguration basicConfig = new DummyConfiguration();
+ oaParam = new DummySpConfiguration(configMap, basicConfig);
+
+ }
+
+ @Test
+ public void checkProcessDefinition() {
+ Assert.assertNotNull("AuthModule is null", authProcess);
+ Assert.assertNotNull("AuthModule process is null", authProcess.getProcessDefinitions());
+
+ for (String el : authProcess.getProcessDefinitions()) {
+ Resource res = loader.getResource(el);
+ Assert.assertTrue("AuthProcess description not extist", res.exists());
+
+ }
+ }
+
+ @Test
+ public void idAustriaAuthSelected() throws Exception {
+ ProxyServicePendingRequest pendingReq = new ProxyServicePendingRequest();
+ pendingReq.setOnlineApplicationConfiguration(oaParam);
+
+ //execute test
+ final String result = moduleReg.selectProcess(executionContext, pendingReq);
+
+ //validate state
+ Assert.assertNotNull("Process is null", result);
+ Assert.assertEquals("Process Id not match", "idAustriaForEidasProxyService", result);
+
+ Assert.assertNotNull("Can not initalize process", processEngine.createProcessInstance(result));
+
+ }
+
+ @Test
+ public void wrongPendingRequestType() throws Exception {
+ TestRequestImpl pendingReq = new TestRequestImpl();
+ pendingReq.setSpConfig(oaParam);
+
+ //execute test
+ final String result = moduleReg.selectProcess(executionContext, pendingReq);
+
+ //validate state
+ Assert.assertNull("AuthProcessName", result);
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/EidasConnecorUniqueIdAttributeBuilderTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/EidasConnecorUniqueIdAttributeBuilderTest.java
new file mode 100644
index 00000000..9f42f5e5
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/EidasConnecorUniqueIdAttributeBuilderTest.java
@@ -0,0 +1,54 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.builder.attributes;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes.EidasConnecorUniqueIdAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.attributes.AbstractAttributeBuilderTest;
+
+/**
+ * Attribute builder to generate an attribute that holds the unique eIDSA-Connector identifier for this process.
+ * <br>
+ * The attribute-value is read from {@link ISpConfiguration} with method <code>getUniqueIdentifier()</code>
+ *
+ * @author tlenz
+ *
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_basic_test.xml",
+})
+public class EidasConnecorUniqueIdAttributeBuilderTest extends AbstractAttributeBuilderTest {
+
+ private final IAttributeBuilder attrBuilder = new EidasConnecorUniqueIdAttributeBuilder();
+
+ @Test
+ public void attributeName() {
+ Assert.assertEquals("Wrong attribute name",
+ "urn:eidgvat:attributes.eidas.uniqueId", attrBuilder.getName());
+
+ }
+
+ @Test
+ public void checkEmptyAttribute() {
+ String value = attrBuilder.buildEmpty(gen);
+ Assert.assertNull("Attr. not null", value);
+
+ }
+
+
+ @Test
+ public void withAttributeValue() throws AttributeBuilderException, Exception {
+ String value = attrBuilder.build(spConfig, buildAuthData(), gen);
+ Assert.assertEquals("wrong attributeValue", spConfig.getUniqueIdentifier(), value);
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/SpRequiredAttributersAttributeBuilderTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/SpRequiredAttributersAttributeBuilderTest.java
new file mode 100644
index 00000000..2fe420df
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/SpRequiredAttributersAttributeBuilderTest.java
@@ -0,0 +1,72 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.builder.attributes;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.internal.util.collections.Sets;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes.SpRequiredAttributersAttributeBuilder;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder;
+import at.gv.egiz.eaaf.core.exceptions.AttributeBuilderException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.attributes.AbstractAttributeBuilderTest;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_basic_test.xml",
+})
+public class SpRequiredAttributersAttributeBuilderTest extends AbstractAttributeBuilderTest {
+
+private final IAttributeBuilder attrBuilder = new SpRequiredAttributersAttributeBuilder();
+
+ @Test
+ public void attributeName() {
+ Assert.assertEquals("Wrong attribute name",
+ "urn:eidgvat:attributes.RequiredAttributes", attrBuilder.getName());
+
+ }
+
+ @Test
+ public void checkEmptyAttribute() {
+ String value = attrBuilder.buildEmpty(gen);
+ Assert.assertNull("Attr. not null", value);
+
+ }
+
+ @Test
+ public void withWrongSpConfig() throws AttributeBuilderException, Exception {
+ String value = attrBuilder.build(spConfig, buildAuthData(), gen);
+ Assert.assertNull("Attr. not null", value);
+
+ }
+
+ @Test
+ public void withAttributeValue() throws AttributeBuilderException, Exception {
+ ServiceProviderConfiguration sp = new ServiceProviderConfiguration(spConfigMap, new DummyConfiguration());
+ sp.setRequestedAttributes(Sets.newSet(
+ "aabbccdd",
+ RandomStringUtils.randomAlphanumeric(10),
+ PvpAttributeDefinitions.BIRTHDATE_NAME));
+
+
+ String value = attrBuilder.build(sp, buildAuthData(), gen);
+
+ List<String> elements = KeyValueUtils.getListOfCsvValues(value);
+ assertEquals("wrong number of attributes", sp.getRequestedAttributes().size(), elements.size());
+ sp.getRequestedAttributes().forEach(
+ el -> elements.contains(el));
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/config/IdAustriaAuthMessageSourceTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/config/IdAustriaAuthMessageSourceTest.java
new file mode 100644
index 00000000..2a92c01e
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/config/IdAustriaAuthMessageSourceTest.java
@@ -0,0 +1,50 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.config;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthMessageSource;
+import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ })
+public class IdAustriaAuthMessageSourceTest {
+
+ @Autowired
+ private ResourceLoader loader;
+ @Autowired(required = false)
+ private List<IMessageSourceLocation> messageSources;
+
+ @Test
+ public void checkMessageSources() {
+ Assert.assertNotNull("No messageSource", messageSources);
+ Assert.assertFalse("No message source", messageSources.isEmpty());
+
+ boolean found = false;
+
+ for (final IMessageSourceLocation messageSource : messageSources) {
+ found = found ? found : messageSource instanceof IdAustriaAuthMessageSource;
+
+ Assert.assertNotNull("No sourcePath", messageSource.getMessageSourceLocation());
+ for (final String el : messageSource.getMessageSourceLocation()) {
+ final Resource messages = loader.getResource(el + ".properties");
+ Assert.assertTrue("Source not exist", messages.exists());
+
+ }
+ }
+
+ Assert.assertTrue("Internal messagesource not found", found);
+
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java
new file mode 100644
index 00000000..0df74f7b
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java
@@ -0,0 +1,186 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.controller;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Before;
+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.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.metadata.resolver.filter.FilterException;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.security.x509.BasicX509Credential;
+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.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.controller.IdAustriaAuthMetadataController;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SimpleMetadataSignatureVerificationFilter;
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_basic_test.xml"
+})
+@EnableWebMvc
+public class IdAustriaAuthMetadataControllerFirstTest {
+
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+
+ @Autowired private IdAustriaAuthMetadataController controller;
+ @Autowired private IdAustriaAuthCredentialProvider credProvider;
+ @Autowired private MsConnectorDummyConfigMap config;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void initialize() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Single jUnit-test set-up.
+ */
+ @Before
+ public void testSetup() {
+ httpReq = new MockHttpServletRequest("GET", "https://localhost/authhandler");
+ httpReq.setContextPath("/authhandler");
+ httpResp = new MockHttpServletResponse();
+
+ //remove additional attributes
+ Map<String, String> attr = config.getBasicConfigurationWithPrefix(
+ "eidas.ms.modules.idaustriaauth.required.additional.attributes.");
+ for (String el : attr.keySet()) {
+ config.removeConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes." + el);
+
+ }
+
+
+ }
+
+ @Test
+ public void buildMetadataValid() throws IOException, EaafException,
+ XMLParserException, UnmarshallingException, FilterException {
+
+ //build metdata
+ controller.getSpMetadata(httpReq, httpResp);
+
+ //check result
+ validateResponse(16);
+
+ }
+
+ @Test
+ public void buildMetadataValidWithAdditionalAttributes() throws IOException, EaafException,
+ XMLParserException, UnmarshallingException, FilterException {
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.1",
+ PvpAttributeDefinitions.BPK_LIST_NAME + ",true");
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.2",
+ PvpAttributeDefinitions.PVP_VERSION_NAME + ",false");
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.7",
+ PvpAttributeDefinitions.EID_SIGNER_CERTIFICATE_NAME + ",true");
+
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.3", "bbbbb");
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.4", "bbbbb,false,test");
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.5", "bbbbb,nichts");
+ config.putConfigValue("eidas.ms.modules.idaustriaauth.required.additional.attributes.6", "");
+
+ //build metdata
+ controller.getSpMetadata(httpReq, httpResp);
+
+ //check result
+ validateResponse(17);
+
+ }
+
+ private void validateResponse(int numberOfRequestedAttributes) throws UnsupportedEncodingException,
+ XMLParserException, UnmarshallingException, FilterException, CredentialsNotAvailableException {
+ Assert.assertEquals("HTTP Statuscode", 200, httpResp.getStatus());
+ Assert.assertEquals("ContentType", "text/xml; charset=utf-8", httpResp.getContentType());
+ Assert.assertEquals("ContentEncoding", "UTF-8", httpResp.getCharacterEncoding());
+
+ final String metadataXml = httpResp.getContentAsString();
+ Assert.assertNotNull("XML Metadata", metadataXml);
+
+ final EntityDescriptor metadata = (EntityDescriptor) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(), new ByteArrayInputStream(metadataXml.getBytes("UTF-8")));
+
+ Assert.assertEquals("EntityId",
+ "http://localhost/authhandler" + IdAustriaAuthConstants.ENDPOINT_METADATA,
+ metadata.getEntityID());
+
+ MetadataFilterContext filterContext = new MetadataFilterContext();
+
+ //check XML scheme
+ final SchemaValidationFilter schemaFilter = new SchemaValidationFilter();
+ schemaFilter.filter(metadata, filterContext);
+
+ //check signature
+ final SimpleMetadataSignatureVerificationFilter sigFilter =
+ new SimpleMetadataSignatureVerificationFilter(credProvider.getKeyStore().getFirst(),
+ metadata.getEntityID());
+ sigFilter.filter(metadata, filterContext);
+
+ //check content
+ final SPSSODescriptor spSsoDesc = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+ Assert.assertNotNull("SPSSODescr.", spSsoDesc);
+
+ Assert.assertFalse("AssertionConsumerServices",
+ spSsoDesc.getAssertionConsumerServices().isEmpty());
+ Assert.assertTrue("ContactPersons", metadata.getContactPersons().isEmpty());
+ Assert.assertNull("ContactPersons", metadata.getOrganization());
+
+ Assert.assertFalse("KeyDescriptors",
+ spSsoDesc.getKeyDescriptors().isEmpty());
+ Assert.assertEquals("#KeyDescriptors", 2, spSsoDesc.getKeyDescriptors().size());
+
+ Assert.assertFalse("NameIDFormats",
+ spSsoDesc.getNameIDFormats().isEmpty());
+ Assert.assertEquals("wrong NameIDFormats", "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
+ spSsoDesc.getNameIDFormats().get(0).getURI());
+
+ Assert.assertFalse("AttributeConsumingServices",
+ spSsoDesc.getAttributeConsumingServices().isEmpty());
+ Assert.assertEquals("#RequestAttributes", numberOfRequestedAttributes,
+ spSsoDesc.getAttributeConsumingServices().get(0).getRequestedAttributes().size());
+
+ }
+
+ private List<BasicX509Credential> convertX509Certs(List<X509Certificate> certs) {
+ final List<BasicX509Credential> result = new ArrayList<>();
+ for (final X509Certificate cert : certs) {
+ result.add(new BasicX509Credential(cert));
+
+ }
+ return result;
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthSignalControllerTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthSignalControllerTest.java
new file mode 100644
index 00000000..e9ecbc58
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthSignalControllerTest.java
@@ -0,0 +1,200 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.controller;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+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.junit4.SpringJUnit4ClassRunner;
+import org.springframework.util.SerializationUtils;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.controller.IdAustriaAuthSignalController;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyProtocolAuthService;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummySpConfiguration;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.core.impl.idp.process.spring.test.DummyTransactionStorage.DummyDbEntry;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_basic_test.xml"
+})
+@EnableWebMvc
+public class IdAustriaAuthSignalControllerTest {
+
+ @Autowired(required = true)
+ private IdAustriaAuthSignalController controller;
+ @Autowired(required = true)
+ private ITransactionStorage cache;
+ @Autowired(required = true)
+ private IPendingRequestIdGenerationStrategy pendingReqGeneration;
+ @Autowired(required = true)
+ private IRequestStorage reqStorage;
+ @Autowired(required = true)
+ private IConfiguration basicConfig;
+ @Autowired private ITransactionStorage transactionStorage;
+
+ @Autowired private DummyProtocolAuthService protAuthService;
+
+ @Test
+ public void noRelayState() throws IOException, EaafException {
+ final MockHttpServletRequest httpReq =
+ new MockHttpServletRequest("POST", "https://localhost/ms_connectoror");
+ final MockHttpServletResponse httpResp = new MockHttpServletResponse();
+
+ controller.performEidasAuthentication(httpReq, httpResp);
+ Assert.assertEquals("httpStausCode", 200, httpResp.getStatus());
+
+ final String errorId = protAuthService.getErrorKey();
+ final Object error = cache.get(errorId);
+ Assert.assertNotNull("Error is null", error);
+ org.springframework.util.Assert.isInstanceOf(byte[].class,
+ ((DummyDbEntry) error).getObj());
+ final Object errorObj = SerializationUtils.deserialize((byte[]) ((DummyDbEntry) error).getObj());
+ org.springframework.util.Assert.isInstanceOf(ExceptionContainer.class, errorObj);
+ org.springframework.util.Assert.isInstanceOf(EaafException.class,
+ ((ExceptionContainer) errorObj).getExceptionThrown());
+
+ }
+
+ @Test
+ public void validRelayStateNoPendingReqId() throws EaafException, IOException {
+ final String pendingReqId = pendingReqGeneration.generateExternalPendingRequestId();
+ final MockHttpServletRequest httpReq =
+ new MockHttpServletRequest("POST", "https://localhost/ms_connectoror");
+ httpReq.addParameter(IdAustriaAuthSignalController.HTTP_PARAM_RELAYSTATE, pendingReqId);
+ final MockHttpServletResponse httpResp = new MockHttpServletResponse();
+
+ controller.performEidasAuthentication(httpReq, httpResp);
+ Assert.assertEquals("httpStausCode", 200, httpResp.getStatus());
+
+ final String errorId = protAuthService.getErrorKey();
+ final Object error = cache.get(errorId);
+ Assert.assertNotNull("Error is null", error);
+ org.springframework.util.Assert.isInstanceOf(byte[].class,
+ ((DummyDbEntry) error).getObj());
+ final Object errorObj = SerializationUtils.deserialize((byte[]) ((DummyDbEntry) error).getObj());
+ org.springframework.util.Assert.isInstanceOf(ExceptionContainer.class, errorObj);
+ org.springframework.util.Assert.isInstanceOf(EaafException.class,
+ ((ExceptionContainer) errorObj).getExceptionThrown());
+ //TODO:
+ Assert.assertEquals("ErrorCode not match", "auth.26",
+ ((EaafException) ((ExceptionContainer) errorObj).getExceptionThrown()).getErrorId());
+
+ }
+
+ @Test
+ public void validRelayStateSuspectPendingReqId() throws EaafException, IOException {
+ String relayState = RandomStringUtils.randomAlphanumeric(10);
+ transactionStorage.put(relayState, false, -1);
+
+ final MockHttpServletRequest httpReq =
+ new MockHttpServletRequest("POST", "https://localhost/ms_connectoror");
+ httpReq.addParameter(IdAustriaAuthSignalController.HTTP_PARAM_RELAYSTATE, relayState);
+ final MockHttpServletResponse httpResp = new MockHttpServletResponse();
+
+ controller.performEidasAuthentication(httpReq, httpResp);
+ Assert.assertEquals("httpStausCode", 200, httpResp.getStatus());
+
+ final String errorId = protAuthService.getErrorKey();
+ final Object error = cache.get(errorId);
+ Assert.assertNotNull("Error is null", error);
+ org.springframework.util.Assert.isInstanceOf(byte[].class,
+ ((DummyDbEntry) error).getObj());
+ final Object errorObj = SerializationUtils.deserialize((byte[]) ((DummyDbEntry) error).getObj());
+ org.springframework.util.Assert.isInstanceOf(ExceptionContainer.class, errorObj);
+ org.springframework.util.Assert.isInstanceOf(EaafException.class,
+ ((ExceptionContainer) errorObj).getExceptionThrown());
+ //TODO:
+ Assert.assertEquals("ErrorCode not match", "auth.26",
+ ((EaafException) ((ExceptionContainer) errorObj).getExceptionThrown()).getErrorId());
+
+ Assert.assertNull("RelayState was not removed", transactionStorage.get(relayState));
+
+ }
+
+ @Test
+ public void validRelayStateNoPendingReq() throws EaafException, IOException {
+ final String pendingReqId = pendingReqGeneration.generateExternalPendingRequestId();
+ String relayState = RandomStringUtils.randomAlphanumeric(10);
+ transactionStorage.put(relayState, pendingReqId, -1);
+
+ final MockHttpServletRequest httpReq =
+ new MockHttpServletRequest("POST", "https://localhost/ms_connectoror");
+ httpReq.addParameter(IdAustriaAuthSignalController.HTTP_PARAM_RELAYSTATE, relayState);
+ final MockHttpServletResponse httpResp = new MockHttpServletResponse();
+
+ controller.performEidasAuthentication(httpReq, httpResp);
+ Assert.assertEquals("httpStausCode", 200, httpResp.getStatus());
+
+ final String errorId = protAuthService.getErrorKey();
+ final Object error = cache.get(errorId);
+ Assert.assertNotNull("Error is null", error);
+ org.springframework.util.Assert.isInstanceOf(byte[].class,
+ ((DummyDbEntry) error).getObj());
+ final Object errorObj = SerializationUtils.deserialize((byte[]) ((DummyDbEntry) error).getObj());
+ org.springframework.util.Assert.isInstanceOf(ExceptionContainer.class, errorObj);
+ org.springframework.util.Assert.isInstanceOf(EaafException.class,
+ ((ExceptionContainer) errorObj).getExceptionThrown());
+ //TODO:
+ Assert.assertEquals("ErrorCode not match", "auth.28",
+ ((EaafException) ((ExceptionContainer) errorObj).getExceptionThrown()).getErrorId());
+
+ Assert.assertNull("RelayState was not removed", transactionStorage.get(relayState));
+
+ }
+
+ @Test
+ public void validRelayStateWithPendingReq() throws EaafException, IOException {
+ final String pendingReqId = pendingReqGeneration.generateExternalPendingRequestId();
+
+ String relayState = RandomStringUtils.randomAlphanumeric(10);
+ transactionStorage.put(relayState, pendingReqId, -1);
+
+ final TestRequestImpl pendingReq = new TestRequestImpl();
+ pendingReq.setPendingReqId(pendingReqId);
+ pendingReq.setAuthUrl("http://localhost/idp");
+ final Map<String, String> spConfigMap = new HashMap<>();
+ spConfigMap.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "http://test.sp");
+ final DummySpConfiguration spConfig = new DummySpConfiguration(spConfigMap, basicConfig);
+ pendingReq.setSpConfig(spConfig);
+ reqStorage.storePendingRequest(pendingReq);
+
+ final MockHttpServletRequest httpReq =
+ new MockHttpServletRequest("POST", "https://localhost/ms_connectoror");
+ httpReq.addParameter(IdAustriaAuthSignalController.HTTP_PARAM_RELAYSTATE, relayState);
+ final MockHttpServletResponse httpResp = new MockHttpServletResponse();
+
+ controller.performEidasAuthentication(httpReq, httpResp);
+
+ Assert.assertEquals("httpStausCode", 200, httpResp.getStatus());
+
+ final String errorId = protAuthService.getErrorKey();
+ final Object error = cache.get(errorId);
+ Assert.assertNotNull("Error is null", error);
+ org.springframework.util.Assert.isInstanceOf(byte[].class,
+ ((DummyDbEntry) error).getObj());
+ final Object errorObj = SerializationUtils.deserialize((byte[]) ((DummyDbEntry) error).getObj());
+ org.springframework.util.Assert.isInstanceOf(ExceptionContainer.class, errorObj);
+ org.springframework.util.Assert.isInstanceOf(EaafException.class,
+ ((ExceptionContainer) errorObj).getExceptionThrown());
+ Assert.assertEquals("ErrorCode not match",
+ "PendingRequest object is not of type 'RequestImpl.class'",
+ ((EaafException) ((ExceptionContainer) errorObj).getExceptionThrown()).getErrorId());
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java
new file mode 100644
index 00000000..c3be6dad
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java
@@ -0,0 +1,790 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.task;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+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.Issuer;
+import org.opensaml.saml.saml2.core.Response;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.tasks.ReceiveFromIdAustriaSystemTask;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
+import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+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.SamlSigningException;
+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.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnResponseValidationException;
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_basic_test.xml",
+})
+public class ReceiveAuthnResponseTaskTest {
+
+ private static final String METADATA_PATH = "classpath:/data/idp_metadata_classpath_entity.xml";
+
+ @Autowired ApplicationContext context;
+ @Autowired MsConnectorDummyConfigMap config;
+
+ @Autowired IdAustriaAuthMetadataProvider metadataProvider;
+ @Autowired IdAustriaAuthCredentialProvider credentialProvider;
+ @Autowired PvpMetadataResolverFactory metadataFactory;
+ @Autowired IRequestStorage storage;
+
+ final ExecutionContext executionContext = new ExecutionContextImpl();
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+
+ private ProxyServicePendingRequest pendingReq;
+ private ServiceProviderConfiguration oaParam;
+ private Map<String, String> spConfig;
+
+ private ReceiveFromIdAustriaSystemTask task;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void initialize() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * jUnit test set-up.
+ *
+ * @throws Exception In case of an set-up error
+ */
+ @Before
+ public void setUp() throws Exception {
+ task = (ReceiveFromIdAustriaSystemTask) context.getBean("receiveIdAustriaAuthnResponseTask");
+
+ httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
+ httpReq.setScheme("https");
+ httpReq.setServerPort(443);
+ httpReq.setContextPath("/authhandler");
+ httpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID,
+ "classpath:/data/idp_metadata_classpath_entity.xml");
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS, "sig");
+
+ spConfig = new HashMap<>();
+ spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "http://test.com/test");
+ oaParam = new ServiceProviderConfiguration(spConfig, config);
+ oaParam.setRequiredLoA(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH));
+
+ pendingReq = new ProxyServicePendingRequest();
+ pendingReq.initialize(httpReq, config);
+ pendingReq.setPendingRequestId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setOnlineApplicationConfiguration(oaParam);
+
+ metadataProvider.fullyDestroy();
+
+ }
+
+ @Test
+ public void unsupportedHttpMethode() {
+ httpReq = new MockHttpServletRequest("PUT", "https://localhost/ms_connector");
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.03",
+ ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpGetNoMessage() {
+ httpReq = new MockHttpServletRequest("GET", "https://localhost/ms_connector");
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostNoMessage() {
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostMessageNotSigned() throws IOException {
+
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ IOUtils.toByteArray(ReceiveAuthnResponseTaskTest.class.getResourceAsStream(
+ "/data/Response_without_sig_classpath_entityid.xml"))));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostMessageWrongDestinationEndpoint() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ TransformerException, MarshallingException {
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_wrong_destination_endpoint.xml",
+ credentialProvider.getMessageSigningCredential(), true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedNoMetadata() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException {
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_classpath_entityid.xml",
+ credentialProvider.getMessageSigningCredential(), true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.11",
+ ((EaafException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionOutDated() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_classpath_entityid.xml",
+ credentialProvider.getMessageSigningCredential(), false);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((EaafException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionFromWrongIdp() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID,
+ RandomStringUtils.randomAlphabetic(10));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_classpath_entityid.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.08",
+ ((EaafException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedWitError() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_with_error.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.05",
+ ((EaafException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedWitUserStopErrorCode() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_with_error_userstop.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform test
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ Assert.assertTrue("process not cancelled", executionContext.isProcessCancelled());
+ Assert.assertTrue("process not stopped by user", pendingReq.isAbortedByUser());
+ Assert.assertFalse("should not authenticated", pendingReq.isAuthenticated());
+
+ }
+
+ @Test
+ public void httpPostValidSignedWithErrorAndNoSubCode() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_with_error_without_subcode.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.05",
+ ((EaafException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedWithErrorAndEmptySubCode() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_without_sig_with_error_empty_subcode.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.05",
+ ((EaafException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionMissingAttributes() throws IOException, SamlSigningException,
+ Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException {
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_wrong_data.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((EaafException) e.getOriginalException()).getErrorId());
+ Assert.assertEquals("sp.pvp2.06",
+ ((EaafException) ((EaafException) e.getOriginalException()).getCause()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionWrongBpkTarget() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+ZZ");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ final TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("sp.pvp2.12",
+ ((EaafException) e.getOriginalException()).getErrorId());
+ Assert.assertEquals("sp.pvp2.06",
+ ((EaafException) ((EaafException) e.getOriginalException()).getCause()).getErrorId());
+ Assert.assertEquals("module.idaustria.06",
+ ((EaafException) ((EaafException) ((EaafException) e.getOriginalException())
+ .getCause()).getCause()).getErrorId());
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionEidValid() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+XX");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+ assertTrue("eidProcess flag", session.isEidProcess());
+ assertFalse("useMandate flag", session.isMandateUsed());
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkAttributeInSession(session, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkAttributeInSession(session, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/high");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session, PvpAttributeDefinitions.BPK_NAME, "AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+
+ }
+
+
+
+ @Test
+ public void httpPostValidSignedAssertionMinimumAttributes() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+CC");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_minimum.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+
+ checkAttributeInSession(session,PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkAttributeInSession(session,PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkAttributeInSession(session,PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ checkAttributeInSession(session,PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ checkAttributeInSession(session,PvpAttributeDefinitions.BPK_NAME, "AT+CC:QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionEidBpkWithoutPrefix() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+XX");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_bpk_without_prefix.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+
+ checkAttributeInSession(session,PvpAttributeDefinitions.GIVEN_NAME_NAME, "Susi");
+ checkAttributeInSession(session,PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Heinz");
+ checkAttributeInSession(session,PvpAttributeDefinitions.BIRTHDATE_NAME, "1955-01-01");
+ checkAttributeInSession(session,PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/aabbcc");
+ checkAttributeInSession(session,PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session,PvpAttributeDefinitions.BPK_NAME, "QVGm48cqcasfasfsafsafdM4UcyhDTNGYmVdrIoY=");
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionEidWithEidSectorAttr() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+AB");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_with_eid_sector_attr.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+
+ checkAttributeInSession(session,PvpAttributeDefinitions.GIVEN_NAME_NAME, "Susi");
+ checkAttributeInSession(session,PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Heinz");
+ checkAttributeInSession(session,PvpAttributeDefinitions.BIRTHDATE_NAME, "1955-01-01");
+ checkAttributeInSession(session,PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/aabbcc");
+ checkAttributeInSession(session,PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session,PvpAttributeDefinitions.BPK_NAME, "AT+AB:QVGm48cqcasfasfsafsafdM4UcyhDTNGYmVdrIoY=");
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionEidValidWithJurMandate() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+XX");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_with_mandate_jur.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+ assertTrue("eidProcess flag", session.isEidProcess());
+ assertTrue("useMandate flag", session.isMandateUsed());
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkAttributeInSession(session, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkAttributeInSession(session, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/high");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_TYPE_NAME, "Generalvollmacht");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, "Testfirma");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, "999999m");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, "urn:publicid:gv.at:baseid+XERSB");
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session, PvpAttributeDefinitions.BPK_NAME, "AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+ assertNull("find nat. person bpk for mandator", session.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, String.class));
+
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionEidValidWithNatMandate() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+XX");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_with_mandate_nat.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+ assertTrue("eidProcess flag", session.isEidProcess());
+ assertTrue("useMandate flag", session.isMandateUsed());
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkAttributeInSession(session, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkAttributeInSession(session, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/high");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_TYPE_NAME, "GeneralvollmachtBilateral");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, "Gerti");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, "Musterfrau");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "01-02-1941");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:AFSDAFSDFDSFCSDAFASDF=");
+
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session, PvpAttributeDefinitions.BPK_NAME, "AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+
+
+ }
+
+ private void checkAttributeInSession(AuthProcessDataWrapper session, String attrName, String expected) {
+ String value = session.getGenericDataFromSession(attrName, String.class);
+ Assert.assertEquals("wrong attr. value", expected, value);
+
+ }
+
+ private Response initializeResponse(String idpEntityId, String responsePath, EaafX509Credential credential,
+ boolean validConditions) throws SamlSigningException, XMLParserException, UnmarshallingException,
+ Pvp2MetadataException {
+
+ final Response response = (Response) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ ReceiveAuthnResponseTaskTest.class.getResourceAsStream(responsePath));
+ response.setIssueInstant(Instant.now());
+ final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class);
+ issuer.setValue(idpEntityId);
+ response.setIssuer(issuer);
+
+ if (validConditions) {
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(Instant.now().plusSeconds(5*60));
+
+ }
+
+ return Saml2Utils.signSamlObject(response, credential, true);
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java
new file mode 100644
index 00000000..1feb684d
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java
@@ -0,0 +1,478 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.task;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.internal.util.collections.Sets;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.schema.XSString;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.tasks.RequestIdAustriaSystemTask;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
+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.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_basic_test.xml",
+})
+public class RequestIdAustriaSystemTaskTest {
+
+ private static final String METADATA_PATH = "classpath:/data/idp_metadata_classpath_entity.xml";
+ private static final String METADATA_SP_PATH = "classpath:/data/sp_metadata_junit.xml";
+
+ @Autowired ApplicationContext context;
+ @Autowired MsConnectorDummyConfigMap config;
+ @Autowired IdAustriaAuthMetadataProvider metadataProvider;
+ @Autowired PvpMetadataResolverFactory metadataFactory;
+ @Autowired DummyGuiBuilderConfigurationFactory guiBuilderConfigFactory;
+ @Autowired SamlVerificationEngine samlVerifyEngine;
+ @Autowired ITransactionStorage transactionStorage;
+
+ final ExecutionContext executionContext = new ExecutionContextImpl();
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+ private ProxyServicePendingRequest pendingReq;
+ private ServiceProviderConfiguration oaParam;
+ private Map<String, String> spConfig;
+
+ private RequestIdAustriaSystemTask task;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void initialize() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * jUnit test set-up.
+ *
+ * @throws Exception In case of an set-up error
+ */
+ @Before
+ public void setUp() throws Exception {
+ task = (RequestIdAustriaSystemTask) context.getBean("createIdAustriaAuthnRequestTask");
+
+ httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler");
+ httpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS, "sig");
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID, METADATA_PATH);
+
+ spConfig = new HashMap<>();
+ spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "http://test.com/test");
+ oaParam = new ServiceProviderConfiguration(spConfig, config);
+ oaParam.setRequiredLoA(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH));
+
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+"
+ + spCountryCode);
+
+ pendingReq = new ProxyServicePendingRequest();
+ pendingReq.initialize(httpReq, config);
+ pendingReq.setPendingRequestId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setOnlineApplicationConfiguration(oaParam);
+
+ metadataProvider.fullyDestroy();
+ guiBuilderConfigFactory.setVelocityBuilderConfig(createDummyGuiConfig());
+
+ }
+
+ @Test
+ public void missingIdAustriaSystemEntiryId() {
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID);
+
+
+ TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("module.idaustria.00",
+ ((EaafConfigurationException) e.getOriginalException()).getErrorId());
+
+
+ }
+
+ @Test
+ public void noMetadataAvailableOnGlobalConfig() {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID,
+ RandomStringUtils.randomAlphabetic(10));
+
+
+ TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class,
+ e.getOriginalException());
+ Assert.assertEquals("module.idaustria.05",
+ ((EaafConfigurationException) e.getOriginalException()).getErrorId());
+
+
+ }
+
+ @Test
+ public void noMetadataSigningKeyStore() throws Pvp2MetadataException {
+ config.removeConfigValue("eidas.ms.modules.idaustriaauth.request.sign.alias");
+
+ metadataProvider.addMetadataResolverIntoChain(
+ metadataFactory.createMetadataProvider(METADATA_PATH, null, "jUnitTest", null));
+
+ TaskExecutionException e = assertThrows(TaskExecutionException.class,
+ () -> task.execute(pendingReq, executionContext));
+
+ Assert.assertNotNull(e.getPendingRequestID());
+ Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID());
+ Assert.assertNotNull(e.getOriginalException());
+ org.springframework.util.Assert.isInstanceOf(CredentialsNotAvailableException.class,
+ e.getOriginalException());
+ Assert.assertEquals("internal.pvp.01",
+ ((CredentialsNotAvailableException) e.getOriginalException()).getErrorId());
+
+ }
+
+ @Test
+ public void successWithoutSpInfos() throws Pvp2InternalErrorException, SecurityException, Exception {
+ metadataProvider.addMetadataResolverIntoChain(
+ metadataFactory.createMetadataProvider(METADATA_PATH, null, "jUnitTest", null));
+
+ LightRequest.Builder eidasRequestBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public");
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+ //execute test
+ task.execute(pendingReq, executionContext);
+
+ //validate state
+ final EaafRequestedAttributes reqAttr = validate();
+ Assert.assertEquals("#Req Attribute", 5, reqAttr.getAttributes().size());
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.eidas.uniqueId",
+ reqAttr.getAttributes().get(0).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(0).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(0).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(0).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value", pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(),
+ ((XSString)reqAttr.getAttributes().get(0).getAttributeValues().get(0)).getValue());
+
+ Assert.assertEquals("Wrong req attr.", "urn:oid:1.2.40.0.10.2.1.1.261.34",
+ reqAttr.getAttributes().get(1).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(1).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(1).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(1).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value", oaParam.getAreaSpecificTargetIdentifier(),
+ ((XSString)reqAttr.getAttributes().get(1).getAttributeValues().get(0)).getValue());
+
+ Assert.assertEquals("Wrong req attr.", "urn:oid:1.2.40.0.10.2.1.1.261.108",
+ reqAttr.getAttributes().get(2).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(1).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(2).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(2).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value", "http://eidas.europa.eu/LoA/high",
+ ((XSString)reqAttr.getAttributes().get(2).getAttributeValues().get(0)).getValue());
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderMandateType",
+ reqAttr.getAttributes().get(4).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(4).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(4).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(4).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value",
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getMandateMode().getMode(),
+ ((XSString)reqAttr.getAttributes().get(4).getAttributeValues().get(0)).getValue());
+
+ }
+
+ @Test
+ public void successWithSpInfos() throws Pvp2InternalErrorException, SecurityException, Exception {
+ metadataProvider.addMetadataResolverIntoChain(
+ metadataFactory.createMetadataProvider(METADATA_PATH, null, "jUnitTest", null));
+
+ LightRequest.Builder eidasRequestBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requesterId(RandomStringUtils.randomAlphanumeric(10))
+ .providerName(RandomStringUtils.randomAlphanumeric(10));
+ LightRequest eidasReq = eidasRequestBuilder.build();
+ pendingReq.setEidasRequest(eidasReq);
+
+ oaParam.setRequestedAttributes(Sets.newSet(
+ "aabbccdd",
+ RandomStringUtils.randomAlphanumeric(10),
+ PvpAttributeDefinitions.BIRTHDATE_NAME));
+
+ //execute test
+ task.execute(pendingReq, executionContext);
+
+ //validate state
+ final EaafRequestedAttributes reqAttr = validate();
+ Assert.assertEquals("#Req Attribute", 7, reqAttr.getAttributes().size());
+
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.RequiredAttributes",
+ reqAttr.getAttributes().get(3).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(3).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(3).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(3).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+
+ List<String> reqProfiles = KeyValueUtils.getListOfCsvValues(
+ ((XSString)reqAttr.getAttributes().get(3).getAttributeValues().get(0)).getValue());
+ reqProfiles.stream().forEach(
+ el -> assertTrue("missing IDA attribute: " + el, oaParam.getRequestedAttributes().contains(el)));
+
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderFriendlyName",
+ reqAttr.getAttributes().get(4).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(4).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(4).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(4).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value", eidasReq.getProviderName(),
+ ((XSString)reqAttr.getAttributes().get(4).getAttributeValues().get(0)).getValue());
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderUniqueId",
+ reqAttr.getAttributes().get(5).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(5).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(5).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(5).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value", eidasReq.getRequesterId(),
+ ((XSString)reqAttr.getAttributes().get(5).getAttributeValues().get(0)).getValue());
+
+
+
+ }
+
+ @Test
+ public void successWithMandates() throws Pvp2InternalErrorException, SecurityException, Exception {
+ metadataProvider.addMetadataResolverIntoChain(
+ metadataFactory.createMetadataProvider(METADATA_PATH, null, "jUnitTest", null));
+
+ LightRequest.Builder eidasRequestBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requesterId(RandomStringUtils.randomAlphanumeric(10))
+ .providerName(RandomStringUtils.randomAlphanumeric(10));
+ LightRequest eidasReq = eidasRequestBuilder.build();
+ pendingReq.setEidasRequest(eidasReq);
+
+ List<String> mandateProfiles = Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ oaParam.setMandateProfiles(mandateProfiles);
+ oaParam.setMandateMode(SpMandateModes.LEGAL_FORCE);
+ //execute test
+ task.execute(pendingReq, executionContext);
+
+ //validate state
+ final EaafRequestedAttributes reqAttr = validate();
+ Assert.assertEquals("#Req Attribute", 8, reqAttr.getAttributes().size());
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderMandateProfiles",
+ reqAttr.getAttributes().get(6).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(6).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(6).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(6).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+
+ List<String> reqProfiles = KeyValueUtils.getListOfCsvValues(
+ ((XSString)reqAttr.getAttributes().get(6).getAttributeValues().get(0)).getValue());
+ reqProfiles.stream().forEach(el -> assertTrue("missing profile: " + el, mandateProfiles.contains(el)));
+
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderMandateType",
+ reqAttr.getAttributes().get(7).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(7).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(7).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(7).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value",
+ SpMandateModes.LEGAL_FORCE.getMode(),
+ ((XSString)reqAttr.getAttributes().get(7).getAttributeValues().get(0)).getValue());
+
+ }
+
+ private EaafRequestedAttributes validate() throws Pvp2InternalErrorException, SecurityException, Exception {
+ Assert.assertEquals("HTTP Statuscode", 200, httpResp.getStatus());
+ Assert.assertEquals("ContentType", "text/html;charset=UTF-8", httpResp.getContentType());
+ Assert.assertEquals("ContentEncoding", "UTF-8", httpResp.getCharacterEncoding());
+
+ final String html = httpResp.getContentAsString();
+ Assert.assertNotNull("XML Metadata", html);
+
+ final int startIndex = html.indexOf("SAMLRequest=");
+ Assert.assertTrue("No SAMLRequest in html", startIndex >= 0);
+ final String authnXml = html.substring(startIndex + "SAMLRequest=".length());
+
+ //check if relaystate was stored
+ final int startIndexRelayState = html.indexOf("RelayState=");
+ Assert.assertTrue("wrong RelayState in HTML",
+ startIndexRelayState >= 0);
+ String relayState = html.substring(startIndexRelayState + "RelayState=".length(), startIndex);
+ String storedPendingReqId = transactionStorage.get(relayState, String.class);
+ Assert.assertEquals("relayStore not map to pendingRequestId",
+ pendingReq.getPendingRequestId(), storedPendingReqId);
+
+
+ final AuthnRequest authnRequest = (AuthnRequest) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(), new ByteArrayInputStream(
+ Base64.getDecoder().decode(authnXml)));
+
+ Assert.assertNotNull("AuthnReq", authnRequest);
+ Assert.assertNotNull("Issuer", authnRequest.getIssuer());
+ Assert.assertEquals("EntityId",
+ "http://localhost" + IdAustriaAuthConstants.ENDPOINT_METADATA,
+ authnRequest.getIssuer().getValue());
+
+ //check XML scheme
+ Saml2Utils.schemeValidation(authnRequest);
+
+ //check signature
+ final PvpSProfileRequest msg = new PvpSProfileRequest(
+ authnRequest,
+ SAMLConstants.SAML2_POST_BINDING_URI);
+ msg.setEntityID(authnRequest.getIssuer().getValue());
+ metadataProvider.addMetadataResolverIntoChain(
+ metadataFactory.createMetadataProvider(METADATA_SP_PATH, null, "jUnit SP", null));
+ samlVerifyEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+
+ //check other elements
+ Assert.assertNotNull("Extensions", authnRequest.getExtensions());
+ Assert.assertFalse("No Requested attributes",
+ authnRequest.getExtensions().getUnknownXMLObjects().isEmpty());
+
+ Assert.assertEquals("#ReqAttributes", 1, authnRequest.getExtensions().getUnknownXMLObjects().size());
+ org.springframework.util.Assert.isInstanceOf(EaafRequestedAttributes.class,
+ authnRequest.getExtensions().getUnknownXMLObjects().get(0), "No Requested Attributes object");
+
+ return (EaafRequestedAttributes) authnRequest.getExtensions().getUnknownXMLObjects().get(0);
+
+ }
+
+ private IVelocityGuiBuilderConfiguration createDummyGuiConfig() {
+ return new IVelocityGuiBuilderConfiguration() {
+
+ @Override
+ public Map<String, Object> getViewParameters() {
+ return null;
+ }
+
+ @Override
+ public String getViewName() {
+ return "SAML2 Post-Binding";
+ }
+
+ @Override
+ public String getDefaultContentType() {
+ return null;
+ }
+
+ @Override
+ public InputStream getTemplate(String viewName) {
+ return RequestIdAustriaSystemTaskTest.class.getResourceAsStream("/data/pvp_postbinding_template.html");
+ }
+
+ @Override
+ public String getClasspathTemplateDir() {
+ return null;
+
+ }
+
+ @Override
+ public boolean isWriteAsynch() {
+ return false;
+
+ }
+ };
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthCredentialProviderTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthCredentialProviderTest.java
new file mode 100644
index 00000000..a0d6c988
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthCredentialProviderTest.java
@@ -0,0 +1,413 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.utils;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+import com.google.common.base.Throwables;
+import com.google.common.collect.FluentIterable;
+
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafFactoryException;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ "/spring/SpringTest-context_lazy.xml"
+ })
+@DirtiesContext
+public class IdAustriaAuthCredentialProviderTest {
+
+ private static final String PATH_JKS = "pvp.jks";
+ private static final String ALIAS_METADATA = "metadata";
+ private static final String ALIAS_SIGN = "signing";
+ private static final String ALIAS_ENC = "encryption";
+ private static final String PASSWORD = "password";
+
+ @Autowired
+ private ApplicationContext context;
+ @Autowired
+ private MsConnectorDummyConfigMap config;
+
+ /**
+ * jUnit test initializer.
+ */
+ @Before
+ public void initialize() {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_PATH, PATH_JKS);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTOREPASSWORD, PASSWORD);
+
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS);
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD);
+
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS);
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD);
+
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS);
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD);
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void noKeyStoreUrl() {
+ config.removeConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_PATH);
+ try {
+ context.getBean(IdAustriaAuthCredentialProvider.class);
+ Assert.fail("No KeyStore not detected");
+
+ } catch (final BeansException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class,
+ e.getCause(), "Wrong exception");
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void noKeyStore() {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_PATH,
+ "src/test/resources/config/notExist.p12");
+ try {
+ context.getBean(IdAustriaAuthCredentialProvider.class);
+ Assert.fail("No KeyStore not detected");
+
+ } catch (final BeansException e) {
+ final Optional<Throwable> eaafException = FluentIterable.from(
+ Throwables.getCausalChain(e)).filter(
+ Predicates.instanceOf(EaafConfigurationException.class)).first();
+ Assert.assertTrue("Wrong exception", eaafException.isPresent());
+ Assert.assertEquals("Wrong errorId", "internal.keystore.06",
+ ((EaafException) eaafException.get()).getErrorId());
+
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void noWrongKeyStorePassword() {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTOREPASSWORD, "test");
+ try {
+ context.getBean(IdAustriaAuthCredentialProvider.class);
+ Assert.fail("No KeyStore not detected");
+
+ } catch (final BeansException e) {
+ final Optional<Throwable> eaafException = FluentIterable.from(
+ Throwables.getCausalChain(e)).filter(
+ Predicates.instanceOf(EaafFactoryException.class)).first();
+ Assert.assertTrue("Wrong exception", eaafException.isPresent());
+ Assert.assertEquals("Wrong errorId", "internal.keystore.06",
+ ((EaafException) eaafException.get()).getErrorId());
+
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void notKeyConfigurationWrongAlias() {
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMetaDataSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMessageSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMessageEncryptionCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void notKeyConfigurationWrongPassword() {
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMetaDataSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMessageSigningCredential();
+ Assert.fail("No message signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD,
+ RandomStringUtils.randomAlphabetic(5));
+ final EaafX509Credential encCred = credential.getMessageEncryptionCredential();
+ Assert.assertNull("No encryption signing credentials not detected", encCred);
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void notKeyConfigurationValidAliasWrongPassword() {
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS,
+ ALIAS_METADATA);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMetaDataSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS,
+ ALIAS_SIGN);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMessageSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS,
+ ALIAS_ENC);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD,
+ RandomStringUtils.randomAlphabetic(5));
+ credential.getMessageEncryptionCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void notKeyConfigurationWrongAliasValidPassword() {
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS,
+ RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD,
+ PASSWORD);
+ credential.getMetaDataSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS,
+ RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD,
+ PASSWORD);
+ credential.getMessageSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS,
+ RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD,
+ PASSWORD);
+ credential.getMessageEncryptionCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void validonfiguration() throws CredentialsNotAvailableException {
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS,
+ ALIAS_METADATA);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD,
+ PASSWORD);
+ credential.getMetaDataSigningCredential();
+
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS,
+ ALIAS_SIGN);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD,
+ PASSWORD);
+ credential.getMessageSigningCredential();
+
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS,
+ ALIAS_ENC);
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD,
+ PASSWORD);
+ credential.getMessageEncryptionCredential();
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void notKeyConfiguration() {
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ try {
+ credential.getMetaDataSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ credential.getMessageSigningCredential();
+ Assert.fail("No message signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ final EaafX509Credential encCred = credential.getMessageEncryptionCredential();
+ Assert.assertNull("No encryption signing credentials not detected", encCred);
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void notKeyConfigurationPkcs12() {
+ config.putConfigValue(IdAustriaAuthConstants.CONFIG_PROPS_KEYSTORE_PATH, "pvp.p12");
+ final IdAustriaAuthCredentialProvider credential = context.getBean(
+ IdAustriaAuthCredentialProvider.class);
+
+ Assert.assertNotNull("Credetialprovider", credential);
+ Assert.assertNotNull("Friendlyname", credential.getFriendlyName());
+
+ try {
+ credential.getMetaDataSigningCredential();
+ Assert.fail("No Metadata signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ credential.getMessageSigningCredential();
+ Assert.fail("No message signing credentials not detected");
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+
+ try {
+ final EaafX509Credential encCred = credential.getMessageEncryptionCredential();
+ Assert.assertNull("No encryption signing credentials not detected", encCred);
+
+ } catch (final CredentialsNotAvailableException e) {
+ Assert.assertTrue("Wrong errorCode", e.getMessage().contains("internal.pvp.01"));
+
+ }
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java
new file mode 100644
index 00000000..d9e73db1
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java
@@ -0,0 +1,236 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.utils;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.saml2.metadata.EntityDescriptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.w3c.dom.Element;
+
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+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.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+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.utils.Saml2Utils;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+import net.shibboleth.utilities.java.support.xml.SerializeSupport;
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+import okhttp3.HttpUrl;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml" })
+public class IdAustriaAuthMetadataProviderFirstTest {
+
+ @Autowired IPvp2CredentialProvider credentialProvider;
+ @Autowired IdAustriaAuthMetadataProvider provider;
+ @Autowired PvpMetadataResolverFactory resolverFactory;
+ @Autowired MsConnectorDummyConfigMap config;
+
+ private static MockWebServer mockWebServer;
+ private static HttpUrl mockServerUrl;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/metadata");
+
+ }
+
+ /**
+ * jUnit test set-up.
+ *
+ * @throws ResolverException
+ *
+ */
+ @Before
+ public void testSetup() {
+ provider.fullyDestroy();
+
+ }
+
+ @Test
+ public void simpleManuelAddingTest() throws Pvp2MetadataException, ResolverException {
+ final IPvp2MetadataProvider resolver1 = resolverFactory.createMetadataProvider(
+ "classpath:/data/idp_metadata_sig_notvalid.xml",
+ null, "junit", null);
+ Assert.assertNotNull("Resolver 1 is null", resolver1);
+ provider.addMetadataResolverIntoChain(resolver1);
+
+ final IPvp2MetadataProvider resolver2 = resolverFactory.createMetadataProvider(
+ "classpath:/data/idp_metadata_sig_valid_wrong_alg.xml",
+ null, "junit", null);
+ Assert.assertNotNull("Resolver 2 is null", resolver2);
+ provider.addMetadataResolverIntoChain(resolver2);
+
+ final EntityDescriptor entity1 = provider.getEntityDescriptor("https://localEntity");
+ Assert.assertNotNull("Entity 1 not found", entity1);
+
+ final EntityDescriptor entity2 = provider.getEntityDescriptor(
+ "https://vidp.gv.at/ms_connector/pvp/metadata");
+ Assert.assertNotNull("Entity 2 not found", entity2);
+
+ final EntityDescriptor entity3 = provider.getEntityDescriptor("https://egiz.gv.at/abababa");
+ Assert.assertNull("Entity 3 found", entity3);
+
+ }
+
+ @Test
+ public void dynamicLoadingNoValidSignature() throws ResolverException {
+ final EntityDescriptor entity = provider.getEntityDescriptor("classpath:/data/idp_metadata_no_sig2.xml");
+ Assert.assertNull("Entity found", entity);
+
+ }
+
+ @Test
+ public void dynamicLoadingValidSignature() throws XMLParserException, UnmarshallingException,
+ SamlSigningException, CredentialsNotAvailableException, MarshallingException, ResolverException {
+
+ final String entityId = injectValidHttpMetadata();
+ final EntityDescriptor entity = provider.getEntityDescriptor(entityId);
+ Assert.assertNotNull("Entity not found", entity);
+
+ }
+
+ @Test
+ public void reloadNotPossible() throws XMLParserException, UnmarshallingException,
+ SamlSigningException, CredentialsNotAvailableException, MarshallingException, ResolverException {
+
+ final String entityId = injectValidHttpMetadata();
+ final EntityDescriptor entity = provider.getEntityDescriptor(entityId);
+ Assert.assertNotNull("Entity not found", entity);
+ Assert.assertNotNull("Entity not found",
+ provider.resolveSingle(generateEntityIdCreteria(entityId)));
+
+ Assert.assertFalse("Refresh should not be possible",
+ provider.refreshMetadataProvider(entityId));
+
+ final EntityDescriptor entity2 = provider.getEntityDescriptor(entityId);
+ Assert.assertNull("Entity not found", entity2);
+ Assert.assertNull("Entity not found",
+ provider.resolveSingle(generateEntityIdCreteria(entityId)));
+
+ Assert.assertFalse("Last refresh", provider.wasLastRefreshSuccess());
+
+ }
+
+ @Test
+ public void refeshTest() throws Pvp2MetadataException, ResolverException {
+ Assert.assertFalse("Last refresh", provider.wasLastRefreshSuccess());
+ Assert.assertNull("LastRefresh", provider.getLastRefresh());
+ Assert.assertNull("LastSuccessfulRefresh", provider.getLastSuccessfulRefresh());
+ Assert.assertNull("LastUpdate", provider.getLastUpdate());
+
+ final IPvp2MetadataProvider resolver1 = resolverFactory.createMetadataProvider(
+ "classpath:/data/idp_metadata_sig_notvalid.xml",
+ null, "junit", null);
+ Assert.assertNotNull("Resolver 1 is null", resolver1);
+ provider.addMetadataResolverIntoChain(resolver1);
+
+ final IPvp2MetadataProvider resolver2 = resolverFactory.createMetadataProvider(
+ "classpath:/data/idp_metadata_sig_valid_wrong_alg.xml",
+ null, "junit", null);
+ Assert.assertNotNull("Resolver 2 is null", resolver2);
+ provider.addMetadataResolverIntoChain(resolver2);
+
+ provider.refresh();
+
+ Assert.assertTrue("Last refresh", provider.wasLastRefreshSuccess());
+ Assert.assertNotNull("LastRefresh", provider.getLastRefresh());
+ Assert.assertNotNull("LastSuccessfulRefresh", provider.getLastSuccessfulRefresh());
+ Assert.assertNotNull("LastUpdate", provider.getLastUpdate());
+
+ }
+
+ @Test
+ public void reloadPossible() throws XMLParserException, UnmarshallingException,
+ SamlSigningException, CredentialsNotAvailableException, MarshallingException, ResolverException,
+ IOException {
+
+ mockWebServer.shutdown();
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/metadata");
+
+ final String entityId = injectValidHttpMetadata();
+ final EntityDescriptor entity = provider.getEntityDescriptor(entityId);
+ Assert.assertNotNull("Entity not found", entity);
+ Assert.assertNotNull("Entity not found",
+ provider.resolveSingle(generateEntityIdCreteria(entityId)));
+
+ Assert.assertFalse("Last refresh", provider.wasLastRefreshSuccess());
+
+ injectValidHttpMetadata(entityId);
+ Assert.assertTrue("Refresh should not be possible",
+ provider.refreshMetadataProvider(entityId));
+
+ final EntityDescriptor entity2 = provider.getEntityDescriptor(entityId);
+ Assert.assertNotNull("Entity not found", entity2);
+ Assert.assertNotNull("Entity not found",
+ provider.resolveSingle(generateEntityIdCreteria(entityId)));
+
+ Assert.assertFalse("Last refresh", provider.wasLastRefreshSuccess());
+
+ }
+
+ private String injectValidHttpMetadata() throws SamlSigningException, CredentialsNotAvailableException,
+ XMLParserException, UnmarshallingException, MarshallingException {
+ return injectValidHttpMetadata(mockServerUrl.url().toString()
+ + "/" + RandomStringUtils.randomAlphabetic(5));
+ }
+
+ private String injectValidHttpMetadata(String dynEntityId) throws XMLParserException,
+ UnmarshallingException,
+ MarshallingException, SamlSigningException, CredentialsNotAvailableException {
+ final EntityDescriptor metadata = (EntityDescriptor) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ IdAustriaAuthMetadataProviderFirstTest.class.getResourceAsStream("/data/idp_metadata_no_sig.xml"));
+ metadata.setValidUntil(Instant.now().plus(1, ChronoUnit.DAYS));
+ metadata.setSignature(null);
+ metadata.setEntityID(dynEntityId);
+ Saml2Utils.signSamlObject(metadata, credentialProvider.getMetaDataSigningCredential(), true);
+ final Element metadataElement = XMLObjectSupport.marshall(metadata);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(SerializeSupport.nodeToString(metadataElement))
+ .setHeader("Content-Type", "text/html;charset=utf-8"));
+
+ return dynEntityId;
+
+ }
+
+ private CriteriaSet generateEntityIdCreteria(String entityId) {
+ final CriteriaSet result = new CriteriaSet();
+ result.add(new EntityIdCriterion(entityId));
+ return result;
+
+ }
+}
diff --git a/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderSecondTest.java b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderSecondTest.java
new file mode 100644
index 00000000..9b3c1a34
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderSecondTest.java
@@ -0,0 +1,65 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.test.utils;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml" })
+public class IdAustriaAuthMetadataProviderSecondTest {
+
+ @Autowired
+ IdAustriaAuthMetadataProvider provider;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * jUnit test set-up.
+ *
+ * @throws ResolverException
+ *
+ */
+ @Before
+ public void testSetup() {
+ provider.fullyDestroy();
+
+ }
+
+ @Test
+ public void notTrustedX509CertsInTrustStore() throws ResolverException {
+ final EntityDescriptor entity = provider.getEntityDescriptor("classpath:/data/idp_metadata_no_sig2.xml");
+ Assert.assertNull("Entity found", entity);
+
+ }
+
+ @Test
+ public void readStaticInfos() {
+ Assert.assertEquals("wrong providerId",
+ IdAustriaAuthMetadataProvider.PROVIDER_ID, provider.getId());
+
+ provider.runGarbageCollector();
+
+ }
+
+}
diff --git a/modules/authmodule_id-austria/src/test/resources/config/junit.jks b/modules/authmodule_id-austria/src/test/resources/config/junit.jks
new file mode 100644
index 00000000..59e6ad13
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/config/junit.jks
Binary files differ
diff --git a/modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties b/modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties
new file mode 100644
index 00000000..66c13dbc
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties
@@ -0,0 +1,44 @@
+## HTTP-client defaults
+eidas.ms.client.http.connection.timeout.socket=1
+eidas.ms.client.http.connection.timeout.connection=1
+eidas.ms.client.http.connection.timeout.request=1
+
+
+## PVP2 S-Profile communication with ID Austria System
+# EntityId and optional metadata of ID Austria System
+eidas.ms.modules.idaustriaauth.idp.entityId=http://junit.idaustria.at/idp
+#eidas.ms.modules.idaustriaauth.idp.metadataUrl=http://junit.idaustria.at/idp/metadata
+
+# SAML2 client configuration
+eidas.ms.modules.idaustriaauth.keystore.type=jks
+#eidas.ms.modules.idaustriaauth.keystore.name=
+eidas.ms.modules.idaustriaauth.keystore.path=junit_test.jks
+eidas.ms.modules.idaustriaauth.keystore.password=password
+eidas.ms.modules.idaustriaauth.metadata.sign.alias=meta
+eidas.ms.modules.idaustriaauth.metadata.sign.password=password
+eidas.ms.modules.idaustriaauth.request.sign.alias=sig
+eidas.ms.modules.idaustriaauth.request.sign.password=password
+eidas.ms.modules.idaustriaauth.response.encryption.alias=enc
+eidas.ms.modules.idaustriaauth.response.encryption.password=password
+
+# TrustStore to validate SAML2 metadata from ID Austria
+eidas.ms.modules.idaustriaauth.truststore.type=jks
+eidas.ms.modules.idaustriaauth.truststore.name=
+eidas.ms.modules.idaustriaauth.truststore.path=junit_test.jks
+eidas.ms.modules.idaustriaauth.truststore.password=password
+
+# Additional requested attributes in SAML2 metadata
+#eidas.ms.modules.idaustriaauth.required.additional.attributes.1=
+#eidas.ms.modules.idaustriaauth.required.additional.attributes.2=
+#eidas.ms.modules.idaustriaauth.required.additional.attributes.3=
+#eidas.ms.modules.idaustriaauth.required.additional.attributes.4=
+
+
+
+## General PVP2 metadata configuration
+eidas.ms.pvp2.metadata.organisation.name=JUnit
+eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit
+eidas.ms.pvp2.metadata.organisation.url=http://junit.test
+eidas.ms.pvp2.metadata.contact.givenname=Max
+eidas.ms.pvp2.metadata.contact.surname=Mustermann
+eidas.ms.pvp2.metadata.contact.email=max@junit.test \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/test/resources/config/junit_test.jks b/modules/authmodule_id-austria/src/test/resources/config/junit_test.jks
new file mode 100644
index 00000000..ee6254a9
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/config/junit_test.jks
Binary files differ
diff --git a/modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jks b/modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jks
new file mode 100644
index 00000000..8fe3b03c
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jks
Binary files differ
diff --git a/modules/authmodule_id-austria/src/test/resources/config/pvp.jks b/modules/authmodule_id-austria/src/test/resources/config/pvp.jks
new file mode 100644
index 00000000..f0a5a09a
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/config/pvp.jks
Binary files differ
diff --git a/modules/authmodule_id-austria/src/test/resources/config/pvp.p12 b/modules/authmodule_id-austria/src/test/resources/config/pvp.p12
new file mode 100644
index 00000000..183342f7
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/config/pvp.p12
Binary files differ
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID.xml
new file mode 100644
index 00000000..8d3c1c66
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</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="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">AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_bpk_without_prefix.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_bpk_without_prefix.xml
new file mode 100644
index 00000000..ec4f451e
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_bpk_without_prefix.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/aabbcc</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="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">Heinz</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">Susi</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">1955-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">QVGm48cqcasfasfsafsafdM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_minimum.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_minimum.xml
new file mode 100644
index 00000000..be8e7cc3
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_minimum.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <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="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">AT+CC:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_eid_sector_attr.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_eid_sector_attr.xml
new file mode 100644
index 00000000..6b86c6f1
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_eid_sector_attr.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/aabbcc</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="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">Heinz</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">Susi</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">1955-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">AT+AB:QVGm48cqcasfasfsafsafdM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="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:eidasid+AT+AB</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml
new file mode 100644
index 00000000..da97bbf4
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</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="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">AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ <saml2:Attribute 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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Generalvollmacht</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">999999m</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">urn:publicid:gv.at:baseid+XERSB</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Testfirma</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml
new file mode 100644
index 00000000..8a84503d
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</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="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">AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ <saml2:Attribute 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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">GeneralvollmachtBilateral</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="MANDATOR-NATURAL-PERSON-BPK" Name="urn:oid:1.2.40.0.10.2.1.1.261.98" 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+XX:AFSDAFSDFDSFCSDAFASDF=</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="MANDATOR-NATURAL-PERSON-GIVEN-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.78" 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">Gerti</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="MANDATOR-NATURAL-PERSON-FAMILY-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.80" 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">Musterfrau</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="MANDATOR-NATURAL-PERSON-BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.82" 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">01-02-1941</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_wrong_data.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_wrong_data.xml
new file mode 100644
index 00000000..cc534d09
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_wrong_data.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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="2035-03-05T06:44:51.017Z" Recipient="https://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <saml2:Attribute FriendlyName="piiTransactionId" Name="urn:eidgvat:attributes.piiTransactionId" 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">piiId_112233445566</saml2:AttributeValue>
+ </saml2:Attribute>
+ <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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/low</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">IT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="eidBind" Name="urn:eidgvat:attributes.eidbind" 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">aabbccddeeffgghh</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="userAuthBlock" Name="urn:eidgvat:attributes.authblock.signed" 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">MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRhMB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SYO4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYIKoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImnAiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_with_wrong_destination_endpoint.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_with_wrong_destination_endpoint.xml
new file mode 100644
index 00000000..2ae05ca1
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_with_wrong_destination_endpoint.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/demoapp/sp/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </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://localhost/authhandler/sp/idaustria/eidas/metadata</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>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_classpath_entityid.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_classpath_entityid.xml
new file mode 100644
index 00000000..0fd675e2
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_classpath_entityid.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </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://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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- 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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</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">IT</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>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error.xml
new file mode 100644
index 00000000..ee5920dc
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
+ <saml2p:StatusCode Value="9199"/>
+ </saml2p:StatusCode>
+ <saml2p:StatusMessage>Der Anmeldevorgang wurde durch den Benutzer abgebrochen.</saml2p:StatusMessage>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </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://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/low</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">IT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="eidBind" Name="urn:eidgvat:attributes.eidbind" 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">aabbccddeeffgghh</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="userConsent" Name="urn:eidgvat:attributes.consent.signed" 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">MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRhMB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SYO4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYIKoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImnAiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_empty_subcode.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_empty_subcode.xml
new file mode 100644
index 00000000..dd3f7908
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_empty_subcode.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
+ <saml2p:StatusCode Value=""/>
+ </saml2p:StatusCode>
+ <saml2p:StatusMessage>Der Anmeldevorgang wurde durch den Benutzer abgebrochen.</saml2p:StatusMessage>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </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://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/low</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">IT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="eidBind" Name="urn:eidgvat:attributes.eidbind" 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">aabbccddeeffgghh</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="userConsent" Name="urn:eidgvat:attributes.consent.signed" 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">MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRhMB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SYO4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYIKoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImnAiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_userstop.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_userstop.xml
new file mode 100644
index 00000000..1783cbab
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_userstop.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
+ <saml2p:StatusCode Value="1005"/>
+ </saml2p:StatusCode>
+ <saml2p:StatusMessage>Der Anmeldevorgang wurde durch den Benutzer abgebrochen.</saml2p:StatusMessage>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </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://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/low</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">IT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="eidBind" Name="urn:eidgvat:attributes.eidbind" 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">aabbccddeeffgghh</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="userConsent" Name="urn:eidgvat:attributes.consent.signed" 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">MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRhMB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SYO4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYIKoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImnAiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_without_subcode.xml b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_without_subcode.xml
new file mode 100644
index 00000000..1c7a8433
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_without_subcode.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
+ </saml2p:StatusCode>
+ <saml2p:StatusMessage>Der Anmeldevorgang wurde durch den Benutzer abgebrochen.</saml2p:StatusMessage>
+ </saml2p:Status>
+ <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://localhost/authhandler/sp/eidas/post"/>
+ </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://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</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="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">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/low</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">IT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="eidBind" Name="urn:eidgvat:attributes.eidbind" 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">aabbccddeeffgghh</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="userConsent" Name="urn:eidgvat:attributes.consent.signed" 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">MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRhMB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SYO4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYIKoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImnAiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/eidas_node_siging.crt b/modules/authmodule_id-austria/src/test/resources/data/eidas_node_siging.crt
new file mode 100644
index 00000000..95843ea9
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/eidas_node_siging.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAn0CBFtIcMwwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxMTAvBgNVBAMMKG5hdGlvbmFsIGNlbnRyYWwgZUlEQVMgbm9kZSAtIHRlc3RzeXN0ZW0wHhcN
+MTgwNzEzMDkyODQ0WhcNMjEwNDA3MDkyODQ0WjBPMQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJ
+WjExMC8GA1UEAwwobmF0aW9uYWwgY2VudHJhbCBlSURBUyBub2RlIC0gdGVzdHN5c3RlbTCCAaIw
+DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALK4bdf5OremKkj0+xCjU0eN7RUd1A2VqoGnvFUs
+t7xjLQ1PspHiDf9Pm2cwOIJabSnuZ01hYAGz9X+lU3Z3fwhVc+tEsuzsaAml/LPw3i3+ppoSTJDM
+iDvhCoUKTzJ8HBQj2gTvXNlqPljyGneuCJ+uBMr7Okq/XjMTJj2xzvutrHS3qIO+/w+OkY967QLV
+RXh0bdFqYqnyAnlYcWJPIwjanOJtE2difPYqers7ZW1F9djP0+IZRoyaook5rpLYvuQTHuvulgIE
+3zGlTuOx3sk8zMyInMndqi75Eh+ROnndSZE7gN3u5CfFpuO5pxFa2jj1h/AnR39Tg8/sU+Se+AwH
+rNvee3IWhxk5LkelYevfeCQos7Dv2ASE9XMCCs7FoE47w8fDalECh09MFKDiotpklbq3OrPg9NQ4
+D//k0GXlW5jYUKP/Wq/+suAI6mfhSnNkjOGMcMlzNTmwxGD/v7Py6OVA+YcJQsqYalLrqbvT2tXV
+mYBVO3oqafg+kfevfwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBgQCioM8k0EEBFtY4QyxOYFufPDLw
+9PNPct01ltnTVjNEEt/L6/8zYlDwrDeULEkJS7mV9zV3657NPQ5IPT/Ib93Uk/RPi0iOA2CGWIMa
+DQIODN3BUYr+zPUqhbKS6OWOhTgV8GiRCUbxrT1uc1AiacP63pga3TJX8k8WFnfW+Dqm2MfWWlxr
+4X2YB9VUW55X5sBNy035jYhEpp8NCK/fTAhoEQNCG+rm3T9qhT6YyOnbW2kXU747+ZwXT2qA5o4y
+a/9+6dDc+LUlHCEm4X7c6bcGvCfNezB4k56FzbAJlOLf2VDGzvEQBf0hsB+kElezm1VBlEkZ4Mjz
+pBpHBMoR21SwTpcvrbR4ig0Bk1eEHNK44sw0F32K5yww3gnJftMIZtPhjhk8UdG2/H6vs9s/to2V
+j4V6wN4o79RTULoQ8RjL6MPWEWzwOvOZXJAo2XJEECvDivSjIJvNC0lfrK3zI3LH3c1JR6q2EfeC
+Z50wTJMFoChSaqunJQXKo81g6wNhP00=
+-----END CERTIFICATE-----
diff --git a/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_classpath_entity.xml b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_classpath_entity.xml
new file mode 100644
index 00000000..de565887
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_classpath_entity.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor
+ xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+ ID="_1a48ec3432f2f3ba6222724a5b06f873"
+ entityID="classpath:/data/idp_metadata_classpath_entity.xml"
+ validUntil="2045-02-06T08:47:26.211Z">
+ <md:IDPSSODescriptor
+ WantAuthnRequestsSigned="true"
+ 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>MIIDMzCCAhsCBFtIcPowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+ SVoxJDAiBgNVBAsMG2NlbnRyYWwgbmF0aW9uYWwgZUlEQVMgbm9kZTEaMBgGA1UEAwwRQXNzZXJ0
+ aW9uIHNpZ25pbmcwHhcNMTgwNzEzMDkyOTMwWhcNMjEwNDA3MDkyOTMwWjBeMQswCQYDVQQGEwJB
+ VDENMAsGA1UECgwERUdJWjEkMCIGA1UECwwbY2VudHJhbCBuYXRpb25hbCBlSURBUyBub2RlMRow
+ GAYDVQQDDBFBc3NlcnRpb24gc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ AJ5zDYxMPRcz6AHaev1tS46Tq8sdgbGFM56uxk6c7LmMDC+HTzNX/3Q5S/YwSzgL3ue5TSw1ltOf
+ yMXMZ6D0+buWWcsxGEkQ8M3adKRFdQrEwafzwTA7pguq5WiHOkr4qwR7dLMome9z5cc3LRcwdOPP
+ gq7ahb5jM3hRqc5xkMWIuvql0NFXPzlHrjDLwy5nIWPOhL5abhVt4YsXbpbjXxFSGkDEAZ32K3EU
+ LNBr9FSUmJfbrVX9AU2T+BKIwiqXP8e/3UJHgPHQ0l5ljWp5P6u5+tvM21o8sUM4eArRa8BkdRsP
+ C92GVuASSUz2ZJ3JhAK1cSM8bnvaZVLQtTvPMAcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAp7z
+ TubWXW6YMpyLSvWBdZiiQ3X66XpSZLZJDIAkoPzEY0DSBp8I5YASIx4JTR5XJt+6MI9acgNIAYW8
+ DhtRwUMVaRWEtuCrfKhGLWm5KSxnhPcD3lzRZhY4ZcA7dUlirjf6hnqo2TFEmJ9fkM+rxwy1GkDD
+ 7j2YDSOFmSq9/Ud9/IbIfSnRu/lO0dh7iRrmg3y0Y/+plPxYmp4AHqehP11OchTz2FGGHVsSC2Vs
+ IVBQI6ANZYyOlicgfEEFHA06jP9OnA0EwEFr2P+di9caZg8vfibyzxMGeuf6CY0c0eLHokBCn2W8
+ vkzvWiER3pozRvCmXFjCVZfRjUunaJf2ow==
+ </ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIC+DCCAeCgAwIBAgIEXh7TbTANBgkqhkiG9w0BAQsFADA+MQswCQYDVQQGEwJB
+ VDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25p
+ bmcwHhcNMjAwMTE1MDg1NTA5WhcNMjkwMTE0MDg1NTA5WjA+MQswCQYDVQQGEwJB
+ VDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25p
+ bmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUSiRjnDvPafZfhJ+L
+ 1wM86FKJX3VIAV/8TD9qJ6HOBkn5WwYfpheyCfRb6XVDyIGpO8qnMWAgC17Ngbmh
+ zj8d8HXNQ2l3uppMv24oUTfXyYhQfZWAghx0sTlRIx/ZmlnduJilx2S53Sa7ruJw
+ lQcBFXj9h9B8dtyegc86Sx6D9BumP1xU7+mEBk8Gv9rR5Khg0Y7qGfZWB0t4aikg
+ aupWveVwiGifOOSfR8czqIg9qUpMYfZiTEBTSRmN6sPiNWhd4J0GyAI9Rn5C9jz/
+ sSlQrxpN+4DXzsqSU5F6gzq3yRux6wyOzDlt2birf21VPQ9HIy4YCjZXwgDWG7AO
+ 821pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADnwdaxUtQU6SIpYwIb2c0ljTmQi
+ 7ryUcUpNHtK0M0E5Mw5Ex8zwrWbNQZ2sUyc4r07M66iOIqHsYZUQlRYvVKHifDpA
+ r8TCgD7iGGdB3By8Ou0RaNW+03w1fwmi98CufbHCGvpv0o2KxlejoHZminNdQ79i
+ bN+01nhocezJQATEQlnwHLiQSjilXpZeLYDk8HbrcUXNRxezN4ChdH+uU54vf+Ux
+ qcj9QHcmBe1+BM8EXfqS1DbTwZl+NTCnh5OYl8fvIFSOHMBxwFrI4pyY0faxg9Uc
+ rCogn/oQ+mV1gnVUDaDhvvEnVGZQtrlt7heVId2BeNellVgsrcmdW8j4U9U=
+ </ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDEN
+ MAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRh
+ MB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQx
+ DTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0
+ YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SY
+ O4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYI
+ KoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImn
+ AiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==
+ </ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
+ </md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ </md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
+ </md:NameIDFormat>
+ <md:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="https://vidp.gv.at/ms_connector/pvp/post" />
+ <md:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="https://vidp.gv.at/ms_connector/pvp/redirect" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SOURCE-PIN"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.36"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SIGNER-CERTIFICATE"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.66"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SOURCE-PIN-TYPE"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.104"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-E-ID-TOKEN"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.39"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ 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" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-IDENTITY-STATUS-LEVEL"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.109"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ </md:IDPSSODescriptor>
+</md:EntityDescriptor>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig.xml b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig.xml
new file mode 100644
index 00000000..bc55fe62
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_1a48ec3432f2f3ba6222724a5b06f873" entityID="https://vidp.gv.at/ms_connector/pvp/metadata" validUntil="2045-02-06T08:47:26.211Z">
+ <md:IDPSSODescriptor WantAuthnRequestsSigned="true" 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>MIIDMzCCAhsCBFtIcPowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxJDAiBgNVBAsMG2NlbnRyYWwgbmF0aW9uYWwgZUlEQVMgbm9kZTEaMBgGA1UEAwwRQXNzZXJ0
+aW9uIHNpZ25pbmcwHhcNMTgwNzEzMDkyOTMwWhcNMjEwNDA3MDkyOTMwWjBeMQswCQYDVQQGEwJB
+VDENMAsGA1UECgwERUdJWjEkMCIGA1UECwwbY2VudHJhbCBuYXRpb25hbCBlSURBUyBub2RlMRow
+GAYDVQQDDBFBc3NlcnRpb24gc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJ5zDYxMPRcz6AHaev1tS46Tq8sdgbGFM56uxk6c7LmMDC+HTzNX/3Q5S/YwSzgL3ue5TSw1ltOf
+yMXMZ6D0+buWWcsxGEkQ8M3adKRFdQrEwafzwTA7pguq5WiHOkr4qwR7dLMome9z5cc3LRcwdOPP
+gq7ahb5jM3hRqc5xkMWIuvql0NFXPzlHrjDLwy5nIWPOhL5abhVt4YsXbpbjXxFSGkDEAZ32K3EU
+LNBr9FSUmJfbrVX9AU2T+BKIwiqXP8e/3UJHgPHQ0l5ljWp5P6u5+tvM21o8sUM4eArRa8BkdRsP
+C92GVuASSUz2ZJ3JhAK1cSM8bnvaZVLQtTvPMAcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAp7z
+TubWXW6YMpyLSvWBdZiiQ3X66XpSZLZJDIAkoPzEY0DSBp8I5YASIx4JTR5XJt+6MI9acgNIAYW8
+DhtRwUMVaRWEtuCrfKhGLWm5KSxnhPcD3lzRZhY4ZcA7dUlirjf6hnqo2TFEmJ9fkM+rxwy1GkDD
+7j2YDSOFmSq9/Ud9/IbIfSnRu/lO0dh7iRrmg3y0Y/+plPxYmp4AHqehP11OchTz2FGGHVsSC2Vs
+IVBQI6ANZYyOlicgfEEFHA06jP9OnA0EwEFr2P+di9caZg8vfibyzxMGeuf6CY0c0eLHokBCn2W8
+vkzvWiER3pozRvCmXFjCVZfRjUunaJf2ow==</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://vidp.gv.at/ms_connector/pvp/post"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://vidp.gv.at/ms_connector/pvp/redirect"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.36" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SIGNER-CERTIFICATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.66" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.104" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-E-ID-TOKEN" Name="urn:oid:1.2.40.0.10.2.1.1.261.39" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-IDENTITY-STATUS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.109" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ </md:IDPSSODescriptor>
+</md:EntityDescriptor>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig2.xml b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig2.xml
new file mode 100644
index 00000000..bdc176a0
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig2.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_1a48ec3432f2f3ba6222724a5b06f873" entityID="classpath:/data/idp_metadata_no_sig2.xml" validUntil="2045-02-06T08:47:26.211Z">
+ <md:IDPSSODescriptor WantAuthnRequestsSigned="true" 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>MIIDMzCCAhsCBFtIcPowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxJDAiBgNVBAsMG2NlbnRyYWwgbmF0aW9uYWwgZUlEQVMgbm9kZTEaMBgGA1UEAwwRQXNzZXJ0
+aW9uIHNpZ25pbmcwHhcNMTgwNzEzMDkyOTMwWhcNMjEwNDA3MDkyOTMwWjBeMQswCQYDVQQGEwJB
+VDENMAsGA1UECgwERUdJWjEkMCIGA1UECwwbY2VudHJhbCBuYXRpb25hbCBlSURBUyBub2RlMRow
+GAYDVQQDDBFBc3NlcnRpb24gc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJ5zDYxMPRcz6AHaev1tS46Tq8sdgbGFM56uxk6c7LmMDC+HTzNX/3Q5S/YwSzgL3ue5TSw1ltOf
+yMXMZ6D0+buWWcsxGEkQ8M3adKRFdQrEwafzwTA7pguq5WiHOkr4qwR7dLMome9z5cc3LRcwdOPP
+gq7ahb5jM3hRqc5xkMWIuvql0NFXPzlHrjDLwy5nIWPOhL5abhVt4YsXbpbjXxFSGkDEAZ32K3EU
+LNBr9FSUmJfbrVX9AU2T+BKIwiqXP8e/3UJHgPHQ0l5ljWp5P6u5+tvM21o8sUM4eArRa8BkdRsP
+C92GVuASSUz2ZJ3JhAK1cSM8bnvaZVLQtTvPMAcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAp7z
+TubWXW6YMpyLSvWBdZiiQ3X66XpSZLZJDIAkoPzEY0DSBp8I5YASIx4JTR5XJt+6MI9acgNIAYW8
+DhtRwUMVaRWEtuCrfKhGLWm5KSxnhPcD3lzRZhY4ZcA7dUlirjf6hnqo2TFEmJ9fkM+rxwy1GkDD
+7j2YDSOFmSq9/Ud9/IbIfSnRu/lO0dh7iRrmg3y0Y/+plPxYmp4AHqehP11OchTz2FGGHVsSC2Vs
+IVBQI6ANZYyOlicgfEEFHA06jP9OnA0EwEFr2P+di9caZg8vfibyzxMGeuf6CY0c0eLHokBCn2W8
+vkzvWiER3pozRvCmXFjCVZfRjUunaJf2ow==</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://vidp.gv.at/ms_connector/pvp/post"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://vidp.gv.at/ms_connector/pvp/redirect"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.36" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SIGNER-CERTIFICATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.66" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.104" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-E-ID-TOKEN" Name="urn:oid:1.2.40.0.10.2.1.1.261.39" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-IDENTITY-STATUS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.109" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ </md:IDPSSODescriptor>
+</md:EntityDescriptor>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_notvalid.xml b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_notvalid.xml
new file mode 100644
index 00000000..86665a9c
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_notvalid.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_1a48ec3432f2f3ba6222724a5b06f873" entityID="https://localEntity" validUntil="2045-02-06T08:47:26.211Z">
+ <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="#_1a48ec3432f2f3ba6222724a5b06f873">
+ <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>e6DiHa9scuvxJFBUipZ8PQcD4kAkmSIDZgZV+0/7glg=</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>Czr2EwhK/0ZUZ5blQpJfNoOFEscLlxlmHPjmOJUIsxlB2pUn+ApULrjVpR1ViUcGZ0PVi2KChSNoSn09YKjtgPFBiSY010VYdaACgqluxUt6AwESObaqcyHVBzMDUr/g6jkRFEJV4vqnZQQDdDfTH4MXNqunORegS1saBHw4nJSOX4YfoVmIuT5uOlRrxvoG7srnGShvF7DmvIHBUBF5Tq9FyeSgwTM8udxl8Yl9FB2pREuR83CcbgjPrYKtzi6TiSfrWkcD0L5BvmMxN/BdaGDAorxYOnk41sWDJjrkY8C2SC1YDy6XT4SM06uFwstUrRn8QPg1hfbLHAyQNoaR8ecgapk5DkxmbATMcGY+SM4yQWkBdYT7GtufNmF8sIVaL6JOOTKAE9qqX/1N6N4zOPmm8rpIqVEQZtQ5usN/ubxbxLxUoTdDeo8RwkktW6zQ3Zv9+Iyf0DASYmK1IxN+fMw/qyeVy9r6o15ITHTqTmT/7BidKZ58m4HxIK52E3DU</ds:SignatureValue>
+ <ds:KeyInfo>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIEFTCCAn0CBFtIcMwwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxMTAvBgNVBAMMKG5hdGlvbmFsIGNlbnRyYWwgZUlEQVMgbm9kZSAtIHRlc3RzeXN0ZW0wHhcN
+MTgwNzEzMDkyODQ0WhcNMjEwNDA3MDkyODQ0WjBPMQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJ
+WjExMC8GA1UEAwwobmF0aW9uYWwgY2VudHJhbCBlSURBUyBub2RlIC0gdGVzdHN5c3RlbTCCAaIw
+DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALK4bdf5OremKkj0+xCjU0eN7RUd1A2VqoGnvFUs
+t7xjLQ1PspHiDf9Pm2cwOIJabSnuZ01hYAGz9X+lU3Z3fwhVc+tEsuzsaAml/LPw3i3+ppoSTJDM
+iDvhCoUKTzJ8HBQj2gTvXNlqPljyGneuCJ+uBMr7Okq/XjMTJj2xzvutrHS3qIO+/w+OkY967QLV
+RXh0bdFqYqnyAnlYcWJPIwjanOJtE2difPYqers7ZW1F9djP0+IZRoyaook5rpLYvuQTHuvulgIE
+3zGlTuOx3sk8zMyInMndqi75Eh+ROnndSZE7gN3u5CfFpuO5pxFa2jj1h/AnR39Tg8/sU+Se+AwH
+rNvee3IWhxk5LkelYevfeCQos7Dv2ASE9XMCCs7FoE47w8fDalECh09MFKDiotpklbq3OrPg9NQ4
+D//k0GXlW5jYUKP/Wq/+suAI6mfhSnNkjOGMcMlzNTmwxGD/v7Py6OVA+YcJQsqYalLrqbvT2tXV
+mYBVO3oqafg+kfevfwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBgQCioM8k0EEBFtY4QyxOYFufPDLw
+9PNPct01ltnTVjNEEt/L6/8zYlDwrDeULEkJS7mV9zV3657NPQ5IPT/Ib93Uk/RPi0iOA2CGWIMa
+DQIODN3BUYr+zPUqhbKS6OWOhTgV8GiRCUbxrT1uc1AiacP63pga3TJX8k8WFnfW+Dqm2MfWWlxr
+4X2YB9VUW55X5sBNy035jYhEpp8NCK/fTAhoEQNCG+rm3T9qhT6YyOnbW2kXU747+ZwXT2qA5o4y
+a/9+6dDc+LUlHCEm4X7c6bcGvCfNezB4k56FzbAJlOLf2VDGzvEQBf0hsB+kElezm1VBlEkZ4Mjz
+pBpHBMoR21SwTpcvrbR4ig0Bk1eEHNK44sw0F32K5yww3gnJftMIZtPhjhk8UdG2/H6vs9s/to2V
+j4V6wN4o79RTULoQ8RjL6MPWEWzwOvOZXJAo2XJEECvDivSjIJvNC0lfrK3zI3LH3c1JR6q2EfeC
+Z50wTJMFoChSaqunJQXKo81g6wNhP00=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </ds:Signature>
+ <md:IDPSSODescriptor WantAuthnRequestsSigned="true" 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>MIIDMzCCAhsCBFtIcPowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxJDAiBgNVBAsMG2NlbnRyYWwgbmF0aW9uYWwgZUlEQVMgbm9kZTEaMBgGA1UEAwwRQXNzZXJ0
+aW9uIHNpZ25pbmcwHhcNMTgwNzEzMDkyOTMwWhcNMjEwNDA3MDkyOTMwWjBeMQswCQYDVQQGEwJB
+VDENMAsGA1UECgwERUdJWjEkMCIGA1UECwwbY2VudHJhbCBuYXRpb25hbCBlSURBUyBub2RlMRow
+GAYDVQQDDBFBc3NlcnRpb24gc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJ5zDYxMPRcz6AHaev1tS46Tq8sdgbGFM56uxk6c7LmMDC+HTzNX/3Q5S/YwSzgL3ue5TSw1ltOf
+yMXMZ6D0+buWWcsxGEkQ8M3adKRFdQrEwafzwTA7pguq5WiHOkr4qwR7dLMome9z5cc3LRcwdOPP
+gq7ahb5jM3hRqc5xkMWIuvql0NFXPzlHrjDLwy5nIWPOhL5abhVt4YsXbpbjXxFSGkDEAZ32K3EU
+LNBr9FSUmJfbrVX9AU2T+BKIwiqXP8e/3UJHgPHQ0l5ljWp5P6u5+tvM21o8sUM4eArRa8BkdRsP
+C92GVuASSUz2ZJ3JhAK1cSM8bnvaZVLQtTvPMAcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAp7z
+TubWXW6YMpyLSvWBdZiiQ3X66XpSZLZJDIAkoPzEY0DSBp8I5YASIx4JTR5XJt+6MI9acgNIAYW8
+DhtRwUMVaRWEtuCrfKhGLWm5KSxnhPcD3lzRZhY4ZcA7dUlirjf6hnqo2TFEmJ9fkM+rxwy1GkDD
+7j2YDSOFmSq9/Ud9/IbIfSnRu/lO0dh7iRrmg3y0Y/+plPxYmp4AHqehP11OchTz2FGGHVsSC2Vs
+IVBQI6ANZYyOlicgfEEFHA06jP9OnA0EwEFr2P+di9caZg8vfibyzxMGeuf6CY0c0eLHokBCn2W8
+vkzvWiER3pozRvCmXFjCVZfRjUunaJf2ow==</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://vidp.gv.at/ms_connector/pvp/post"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://vidp.gv.at/ms_connector/pvp/redirect"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.36" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SIGNER-CERTIFICATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.66" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.104" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-E-ID-TOKEN" Name="urn:oid:1.2.40.0.10.2.1.1.261.39" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-IDENTITY-STATUS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.109" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ </md:IDPSSODescriptor>
+</md:EntityDescriptor>
diff --git a/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_valid_wrong_alg.xml b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_valid_wrong_alg.xml
new file mode 100644
index 00000000..2187aa5f
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_valid_wrong_alg.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_1a48ec3432f2f3ba6222724a5b06f873" entityID="https://vidp.gv.at/ms_connector/pvp/metadata" validUntil="2045-02-06T08:47:26.211Z">
+ <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Id="signature-1-1"><dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><dsig:Reference Id="reference-1-1" URI=""><dsig:Transforms><dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><dsig:DigestValue>dhkHkgZ1OOHG0nYWiRXrpZhIAx41103CG6DKDbBra8o=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>AkxnEu9g3QgYC0JwuJXMYFrnNn6UMtrbtVn5YzkKBXxyYqZui4pEi/TRSM9r7Gt+
+4UqHrJVkYMbbuoO2kpiDnluPG+vHYzYFvF0agQ+gfGjpVQNRORN0FU7JPX+KPjpr
+sMU8wVZITSPU0GBBccvzrcpq7DQt0VbV5U7/Vq3KM/fop4ytAkUbTltUj/XxvAd1
+XdhB/zyeTTR2dafJ6Z2CKyM7MMmxwXYD1NrPGciPvTJ9ASHAT0lJM1dxrRNbeAja
+KTrNVj78MhSluRm5g7N1pMZzgMSpqN66AUg8pkSTvcRaNImPzYDcMQzHl2Tr362M
+RudjSgaEljK98TbBdgLFTg==</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIIEqzCCBBSgAwIBAgIHANux81oNezANBgkqhkiG9w0BAQUFADBAMSIwIAYDVQQD
+ExlJQUlLIFRlc3QgSW50ZXJtZWRpYXRlIENBMQ0wCwYDVQQKEwRJQUlLMQswCQYD
+VQQGEwJBVDAeFw0xMzA5MjcwNTMzMzdaFw0yMzA5MjcwNTMzMzdaMIHkMQswCQYD
+VQQGEwJBVDENMAsGA1UEBxMER3JhejEmMCQGA1UEChMdR3JheiBVbml2ZXJzaXR5
+IG9mIFRlY2hub2xvZ3kxSDBGBgNVBAsTP0luc3RpdHV0ZSBmb3IgQXBwbGllZCBJ
+bmZvcm1hdGlvbiBQcm9jZXNzaW5nIGFuZCBDb21tdW5pY2F0aW9uczEUMBIGA1UE
+BBMLTU9BLVNTIFRlc3QxGDAWBgNVBCoTD0VHSVogVGVzdHBvcnRhbDEkMCIGA1UE
+AxMbRUdJWiBUZXN0cG9ydGFsIE1PQS1TUyBUZXN0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAuDjOyf+mY+oQL2FQzzuaiC8C23vVKbq/n2Zi7BqSibZH
+mtqMJfmj4pT+hWSNHvVvWsaxFcx4KeNqdCMzwnw1r4P3Sf+2o5uFku5KHEMLMokR
+yYQG9VqY/KkB94ye7Pv6zT8gvKqxGFg96UamECep4swPaSZrA8AOER5WAtyGDzKI
+Tz+a5zfFaTXDoba7f98PCWR96yKiFjVOhzp38WVz4VJgz+b8ZSY7Xsv5Kn7DXjOL
+STX4MevFLki3rFPup3+4vGToaMBW3PEj67HXBdqR855Le6+E6rVxORqsXqlVwhsI
+6nuS0CO2LWYmBNR1IB0mXteeYH/HfxvuZc+7yDjdPQIDAQABo4IBhDCCAYAwDgYD
+VR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFEmcH6VY4BG1EAGB
+TLoNR9vH/g6yMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ei5hdC9jYXBzby9jcmxzL0lBSUtUZXN0X0ludGVybWVkaWF0ZUNBLmNybDCBqgYI
+KwYBBQUHAQEEgZ0wgZowSgYIKwYBBQUHMAGGPmh0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ei5hdC9jYXBzby9PQ1NQP2NhPUlBSUtUZXN0X0ludGVybWVkaWF0ZUNBMEwGCCsG
+AQUFBzAChkBodHRwOi8vY2EuaWFpay50dWdyYXouYXQvY2Fwc28vY2VydHMvSUFJ
+S1Rlc3RfSW50ZXJtZWRpYXRlQ0EuY2VyMCEGA1UdEQQaMBiBFnRob21hcy5sZW56
+QGVnaXouZ3YuYXQwHwYDVR0jBBgwFoAUaKJeEdreL4BrRES/jfplNoEkp28wDQYJ
+KoZIhvcNAQEFBQADgYEAlFGjUxXLs7SAT8NtXSrv2WrjlklaRnHTFHLQwyVo8JWb
+gvRkHHDUv2o8ofXUY2R2WJ38dxeDoccgbXrJb/Qhi8IY7YhCwv/TuIZDisyAqo8W
+ORKSip/6HWlGCSR/Vgoet1GtCmF0FoUxFUIGSAuQ2yyt4fIzt5GJrU1X5ujjI1w=</dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo></dsig:Signature><md:IDPSSODescriptor WantAuthnRequestsSigned="true" 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>MIIDMzCCAhsCBFtIcPowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxJDAiBgNVBAsMG2NlbnRyYWwgbmF0aW9uYWwgZUlEQVMgbm9kZTEaMBgGA1UEAwwRQXNzZXJ0
+aW9uIHNpZ25pbmcwHhcNMTgwNzEzMDkyOTMwWhcNMjEwNDA3MDkyOTMwWjBeMQswCQYDVQQGEwJB
+VDENMAsGA1UECgwERUdJWjEkMCIGA1UECwwbY2VudHJhbCBuYXRpb25hbCBlSURBUyBub2RlMRow
+GAYDVQQDDBFBc3NlcnRpb24gc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJ5zDYxMPRcz6AHaev1tS46Tq8sdgbGFM56uxk6c7LmMDC+HTzNX/3Q5S/YwSzgL3ue5TSw1ltOf
+yMXMZ6D0+buWWcsxGEkQ8M3adKRFdQrEwafzwTA7pguq5WiHOkr4qwR7dLMome9z5cc3LRcwdOPP
+gq7ahb5jM3hRqc5xkMWIuvql0NFXPzlHrjDLwy5nIWPOhL5abhVt4YsXbpbjXxFSGkDEAZ32K3EU
+LNBr9FSUmJfbrVX9AU2T+BKIwiqXP8e/3UJHgPHQ0l5ljWp5P6u5+tvM21o8sUM4eArRa8BkdRsP
+C92GVuASSUz2ZJ3JhAK1cSM8bnvaZVLQtTvPMAcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAp7z
+TubWXW6YMpyLSvWBdZiiQ3X66XpSZLZJDIAkoPzEY0DSBp8I5YASIx4JTR5XJt+6MI9acgNIAYW8
+DhtRwUMVaRWEtuCrfKhGLWm5KSxnhPcD3lzRZhY4ZcA7dUlirjf6hnqo2TFEmJ9fkM+rxwy1GkDD
+7j2YDSOFmSq9/Ud9/IbIfSnRu/lO0dh7iRrmg3y0Y/+plPxYmp4AHqehP11OchTz2FGGHVsSC2Vs
+IVBQI6ANZYyOlicgfEEFHA06jP9OnA0EwEFr2P+di9caZg8vfibyzxMGeuf6CY0c0eLHokBCn2W8
+vkzvWiER3pozRvCmXFjCVZfRjUunaJf2ow==</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://vidp.gv.at/ms_connector/pvp/post"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://vidp.gv.at/ms_connector/pvp/redirect"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.36" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SIGNER-CERTIFICATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.66" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.104" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-E-ID-TOKEN" Name="urn:oid:1.2.40.0.10.2.1.1.261.39" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" 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"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-IDENTITY-STATUS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.109" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ </md:IDPSSODescriptor>
+</md:EntityDescriptor> \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/test/resources/data/junit_keystore_metadata.crt b/modules/authmodule_id-austria/src/test/resources/data/junit_keystore_metadata.crt
new file mode 100644
index 00000000..35831d03
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/junit_keystore_metadata.crt
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDEN
+MAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRh
+MB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQx
+DTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0
+YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SY
+O4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYI
+KoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImn
+AiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==
+-----END CERTIFICATE-----
+
diff --git a/modules/authmodule_id-austria/src/test/resources/data/junit_keystore_signing.crt b/modules/authmodule_id-austria/src/test/resources/data/junit_keystore_signing.crt
new file mode 100644
index 00000000..35a82125
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/junit_keystore_signing.crt
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC+DCCAeCgAwIBAgIEXh7TbTANBgkqhkiG9w0BAQsFADA+MQswCQYDVQQGEwJB
+VDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25p
+bmcwHhcNMjAwMTE1MDg1NTA5WhcNMjkwMTE0MDg1NTA5WjA+MQswCQYDVQQGEwJB
+VDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25p
+bmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUSiRjnDvPafZfhJ+L
+1wM86FKJX3VIAV/8TD9qJ6HOBkn5WwYfpheyCfRb6XVDyIGpO8qnMWAgC17Ngbmh
+zj8d8HXNQ2l3uppMv24oUTfXyYhQfZWAghx0sTlRIx/ZmlnduJilx2S53Sa7ruJw
+lQcBFXj9h9B8dtyegc86Sx6D9BumP1xU7+mEBk8Gv9rR5Khg0Y7qGfZWB0t4aikg
+aupWveVwiGifOOSfR8czqIg9qUpMYfZiTEBTSRmN6sPiNWhd4J0GyAI9Rn5C9jz/
+sSlQrxpN+4DXzsqSU5F6gzq3yRux6wyOzDlt2birf21VPQ9HIy4YCjZXwgDWG7AO
+821pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADnwdaxUtQU6SIpYwIb2c0ljTmQi
+7ryUcUpNHtK0M0E5Mw5Ex8zwrWbNQZ2sUyc4r07M66iOIqHsYZUQlRYvVKHifDpA
+r8TCgD7iGGdB3By8Ou0RaNW+03w1fwmi98CufbHCGvpv0o2KxlejoHZminNdQ79i
+bN+01nhocezJQATEQlnwHLiQSjilXpZeLYDk8HbrcUXNRxezN4ChdH+uU54vf+Ux
+qcj9QHcmBe1+BM8EXfqS1DbTwZl+NTCnh5OYl8fvIFSOHMBxwFrI4pyY0faxg9Uc
+rCogn/oQ+mV1gnVUDaDhvvEnVGZQtrlt7heVId2BeNellVgsrcmdW8j4U9U=
+-----END CERTIFICATE-----
diff --git a/modules/authmodule_id-austria/src/test/resources/data/moa_sig_signing.crt b/modules/authmodule_id-austria/src/test/resources/data/moa_sig_signing.crt
new file mode 100644
index 00000000..fda99f2b
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/moa_sig_signing.crt
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqzCCBBSgAwIBAgIHANux81oNezANBgkqhkiG9w0BAQUFADBAMSIwIAYDVQQD
+ExlJQUlLIFRlc3QgSW50ZXJtZWRpYXRlIENBMQ0wCwYDVQQKEwRJQUlLMQswCQYD
+VQQGEwJBVDAeFw0xMzA5MjcwNTMzMzdaFw0yMzA5MjcwNTMzMzdaMIHkMQswCQYD
+VQQGEwJBVDENMAsGA1UEBxMER3JhejEmMCQGA1UEChMdR3JheiBVbml2ZXJzaXR5
+IG9mIFRlY2hub2xvZ3kxSDBGBgNVBAsTP0luc3RpdHV0ZSBmb3IgQXBwbGllZCBJ
+bmZvcm1hdGlvbiBQcm9jZXNzaW5nIGFuZCBDb21tdW5pY2F0aW9uczEUMBIGA1UE
+BBMLTU9BLVNTIFRlc3QxGDAWBgNVBCoTD0VHSVogVGVzdHBvcnRhbDEkMCIGA1UE
+AxMbRUdJWiBUZXN0cG9ydGFsIE1PQS1TUyBUZXN0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAuDjOyf+mY+oQL2FQzzuaiC8C23vVKbq/n2Zi7BqSibZH
+mtqMJfmj4pT+hWSNHvVvWsaxFcx4KeNqdCMzwnw1r4P3Sf+2o5uFku5KHEMLMokR
+yYQG9VqY/KkB94ye7Pv6zT8gvKqxGFg96UamECep4swPaSZrA8AOER5WAtyGDzKI
+Tz+a5zfFaTXDoba7f98PCWR96yKiFjVOhzp38WVz4VJgz+b8ZSY7Xsv5Kn7DXjOL
+STX4MevFLki3rFPup3+4vGToaMBW3PEj67HXBdqR855Le6+E6rVxORqsXqlVwhsI
+6nuS0CO2LWYmBNR1IB0mXteeYH/HfxvuZc+7yDjdPQIDAQABo4IBhDCCAYAwDgYD
+VR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFEmcH6VY4BG1EAGB
+TLoNR9vH/g6yMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ei5hdC9jYXBzby9jcmxzL0lBSUtUZXN0X0ludGVybWVkaWF0ZUNBLmNybDCBqgYI
+KwYBBQUHAQEEgZ0wgZowSgYIKwYBBQUHMAGGPmh0dHA6Ly9jYS5pYWlrLnR1Z3Jh
+ei5hdC9jYXBzby9PQ1NQP2NhPUlBSUtUZXN0X0ludGVybWVkaWF0ZUNBMEwGCCsG
+AQUFBzAChkBodHRwOi8vY2EuaWFpay50dWdyYXouYXQvY2Fwc28vY2VydHMvSUFJ
+S1Rlc3RfSW50ZXJtZWRpYXRlQ0EuY2VyMCEGA1UdEQQaMBiBFnRob21hcy5sZW56
+QGVnaXouZ3YuYXQwHwYDVR0jBBgwFoAUaKJeEdreL4BrRES/jfplNoEkp28wDQYJ
+KoZIhvcNAQEFBQADgYEAlFGjUxXLs7SAT8NtXSrv2WrjlklaRnHTFHLQwyVo8JWb
+gvRkHHDUv2o8ofXUY2R2WJ38dxeDoccgbXrJb/Qhi8IY7YhCwv/TuIZDisyAqo8W
+ORKSip/6HWlGCSR/Vgoet1GtCmF0FoUxFUIGSAuQ2yyt4fIzt5GJrU1X5ujjI1w=
+-----END CERTIFICATE-----
diff --git a/modules/authmodule_id-austria/src/test/resources/data/pvp_postbinding_template.html b/modules/authmodule_id-austria/src/test/resources/data/pvp_postbinding_template.html
new file mode 100644
index 00000000..5c65e25a
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/pvp_postbinding_template.html
@@ -0,0 +1,3 @@
+#if($RelayState)RelayState=${RelayState}#end
+#if($SAMLRequest)SAMLRequest=${SAMLRequest}#end
+#if($SAMLResponse)SAMLResponse=${SAMLResponse}#end \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/test/resources/data/sp_metadata_junit.xml b/modules/authmodule_id-austria/src/test/resources/data/sp_metadata_junit.xml
new file mode 100644
index 00000000..32e90604
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/data/sp_metadata_junit.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_1a48ec3432f2f3ba6222724a5b06f873" entityID="http://localhost/sp/idaustria/eidas/metadata" validUntil="2045-02-06T08:47:26.211Z">
+ <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+DCCAeCgAwIBAgIEXh7TbTANBgkqhkiG9w0BAQsFADA+MQswCQYDVQQGEwJBVDENMAsGA1UE
+CgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcwHhcNMjAwMTE1MDg1NTA5
+WhcNMjkwMTE0MDg1NTA5WjA+MQswCQYDVQQGEwJBVDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwF
+alVuaXQxEDAOBgNVBAMMB3NpZ25pbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCU
+SiRjnDvPafZfhJ+L1wM86FKJX3VIAV/8TD9qJ6HOBkn5WwYfpheyCfRb6XVDyIGpO8qnMWAgC17N
+gbmhzj8d8HXNQ2l3uppMv24oUTfXyYhQfZWAghx0sTlRIx/ZmlnduJilx2S53Sa7ruJwlQcBFXj9
+h9B8dtyegc86Sx6D9BumP1xU7+mEBk8Gv9rR5Khg0Y7qGfZWB0t4aikgaupWveVwiGifOOSfR8cz
+qIg9qUpMYfZiTEBTSRmN6sPiNWhd4J0GyAI9Rn5C9jz/sSlQrxpN+4DXzsqSU5F6gzq3yRux6wyO
+zDlt2birf21VPQ9HIy4YCjZXwgDWG7AO821pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADnwdaxU
+tQU6SIpYwIb2c0ljTmQi7ryUcUpNHtK0M0E5Mw5Ex8zwrWbNQZ2sUyc4r07M66iOIqHsYZUQlRYv
+VKHifDpAr8TCgD7iGGdB3By8Ou0RaNW+03w1fwmi98CufbHCGvpv0o2KxlejoHZminNdQ79ibN+0
+1nhocezJQATEQlnwHLiQSjilXpZeLYDk8HbrcUXNRxezN4ChdH+uU54vf+Uxqcj9QHcmBe1+BM8E
+XfqS1DbTwZl+NTCnh5OYl8fvIFSOHMBxwFrI4pyY0faxg9UcrCogn/oQ+mV1gnVUDaDhvvEnVGZQ
+trlt7heVId2BeNellVgsrcmdW8j4U9U=</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>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>
+ </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:EntityDescriptor>
diff --git a/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml b/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml
new file mode 100644
index 00000000..fe9ff441
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml
@@ -0,0 +1,20 @@
+<?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">
+
+ <context:annotation-config />
+
+ <bean id="dummyMapBasedConfiguration"
+ class="at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap">
+ <constructor-arg value="/config/junit_config_1.properties" />
+ <property name="configRootDirSufix" value="src/test/resources/config" />
+ </bean>
+
+</beans> \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml b/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml
new file mode 100644
index 00000000..99778839
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml
@@ -0,0 +1,32 @@
+<?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="classpath:/SpringTest-context_authManager.xml" />
+ <import resource="classpath:/eaaf_pvp.beans.xml" />
+ <import resource="classpath:/spring/id_austria_auth.beans.xml" />
+ <import resource="classpath:/spring/id_austria_task.beans.xml" />
+ <import resource="classpath:/eaaf_pvp_sp.beans.xml" />
+
+ <bean id="dummyPvpConfig"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpConfiguration" />
+
+ <bean id="dummyGuiConfigFactory"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory" />
+
+ <bean id="dummyVelocityBuilder"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyVelocityGuiFormBuilder" />
+
+ <bean id="FinalizeAuthenticationTask"
+ class="at.gv.egiz.eaaf.core.impl.idp.controller.tasks.FinalizeAuthenticationTask"
+ scope="prototype" />
+
+</beans> \ No newline at end of file
diff --git a/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_lazy.xml b/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_lazy.xml
new file mode 100644
index 00000000..5360960b
--- /dev/null
+++ b/modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_lazy.xml
@@ -0,0 +1,24 @@
+<?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" >
+
+ <context:annotation-config />
+
+ <import resource="classpath:/spring/eaaf_utils.beans.xml"/>
+
+ <bean id="idAustriaAuthCredentialProvider"
+ class="at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider"
+ lazy-init="true" />
+
+ <bean id="dummyPvpConfig"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpConfiguration"
+ lazy-init="true" />
+
+</beans>
diff --git a/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/MsEidasNodeConstants.java b/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/MsEidasNodeConstants.java
index 835070b1..68ef4560 100644
--- a/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/MsEidasNodeConstants.java
+++ b/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/MsEidasNodeConstants.java
@@ -31,7 +31,6 @@ import java.util.List;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.impl.data.Triple;
-import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder;
public class MsEidasNodeConstants {
// ************ configuration properties ************
@@ -192,17 +191,7 @@ public class MsEidasNodeConstants {
public static final String EID_BINDING_PUBLIC_KEY_NAME = "urn:eidgvat:attributes.binding.pubkey";
-
-
- // ---- Attribute configuration ------
- public static final String ATTR_EIDAS_PERSONAL_IDENTIFIER =
- AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER + PvpAttributeDefinitions.BPK_NAME;
- public static final String ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER =
- AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER + PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME;
- public static final String ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER =
- AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER
- + PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME;
-
+
public static final String AUTH_DATA_SZR_AUTHBLOCK = "authData_AUTHBLOCK";
public static final String AUTH_DATA_EIDAS_BIND = "authData_EIDAS_BIND";
diff --git a/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/config/ServiceProviderConfiguration.java b/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/config/ServiceProviderConfiguration.java
index 423ca4e1..d2177323 100644
--- a/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/config/ServiceProviderConfiguration.java
+++ b/modules/core_common_lib/src/main/java/at/asitplus/eidas/specific/core/config/ServiceProviderConfiguration.java
@@ -26,6 +26,7 @@ package at.asitplus.eidas.specific.core.config;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -34,9 +35,12 @@ import org.slf4j.LoggerFactory;
import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.impl.idp.conf.SpConfigurationImpl;
+import lombok.Getter;
+import lombok.Setter;
public class ServiceProviderConfiguration extends SpConfigurationImpl {
private static final long serialVersionUID = 1L;
@@ -46,6 +50,21 @@ public class ServiceProviderConfiguration extends SpConfigurationImpl {
private String bpkTargetIdentifier;
private String loaMachtingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM;
+ @Setter
+ @Getter
+ private List<String> mandateProfiles;
+
+ /**
+ * IDA specific requested attributes.
+ */
+ @Getter
+ @Setter
+ private Set<String> requestedAttributes;
+
+ @Getter
+ @Setter
+ private SpMandateModes mandateMode = SpMandateModes.NONE;
+
public ServiceProviderConfiguration(Map<String, String> spConfig, IConfiguration authConfig) {
super(spConfig, authConfig);
diff --git a/modules/core_common_lib/src/test/java/at/asitplus/eidas/specific/core/test/config/dummy/MsConnectorDummyConfigMap.java b/modules/core_common_lib/src/test/java/at/asitplus/eidas/specific/core/test/config/dummy/MsConnectorDummyConfigMap.java
index b4c532d9..59ae5aff 100644
--- a/modules/core_common_lib/src/test/java/at/asitplus/eidas/specific/core/test/config/dummy/MsConnectorDummyConfigMap.java
+++ b/modules/core_common_lib/src/test/java/at/asitplus/eidas/specific/core/test/config/dummy/MsConnectorDummyConfigMap.java
@@ -4,10 +4,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap;
import lombok.Setter;
@@ -62,6 +64,12 @@ public class MsConnectorDummyConfigMap extends DummyAuthConfigMap {
}
@Override
+ public String validateIdpUrl(final URL authReqUrl) throws EaafException {
+ return authReqUrl.toExternalForm();
+
+ }
+
+ @Override
public Map<String, String> getBasicConfigurationWithPrefix(final String prefix) {
return super.getBasicConfigurationWithPrefix(addPrefixToKey(prefix));
diff --git a/modules/core_common_webapp/pom.xml b/modules/core_common_webapp/pom.xml
index 7184f843..2c6c4b5c 100644
--- a/modules/core_common_webapp/pom.xml
+++ b/modules/core_common_webapp/pom.xml
@@ -60,9 +60,25 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito2</artifactId>
<scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>mockwebserver</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
</dependency>
<dependency>
<groupId>at.gv.egiz.eaaf</groupId>
@@ -92,14 +108,7 @@
<artifactId>eaaf_module_pvp2_idp</artifactId>
<scope>test</scope>
<type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>com.squareup.okhttp3</groupId>
- <artifactId>mockwebserver</artifactId>
- <scope>test</scope>
</dependency>
-
-
</dependencies>
<build>
diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java
index 181d5735..5a8992b5 100644
--- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java
+++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java
@@ -24,75 +24,92 @@
package at.asitplus.eidas.specific.core.builder;
import java.time.Instant;
-
-import org.springframework.stereotype.Service;
+import java.util.Optional;
+import java.util.Set;
import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues;
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.auth.data.IAuthProcessDataContainer;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;
import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData;
import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder;
import at.gv.egiz.eaaf.core.impl.idp.auth.data.EidAuthProcessDataWrapper;
import lombok.extern.slf4j.Slf4j;
-@Service("AuthenticationDataBuilder")
@Slf4j
public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder {
+ private static final String ERROR_B11 = "builder.11";
+
@Override
- protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException {
+ protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException {
final EidAuthProcessDataWrapper authProcessData =
- pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
- EidAuthenticationData authData = new EidAuthenticationData();
-
- //set basis infos
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
+ final EidAuthenticationData authData = new EidAuthenticationData();
+
+ // set basis infos
super.generateDeprecatedBasicAuthData(authData, pendingReq, authProcessData);
-
+
// set specific informations
authData.setSsoSessionValidTo(
Instant.now().plusSeconds(MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60));
-
-
- authData.setEidStatus(authProcessData.isTestIdentity()
- ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY);
-
+ authData.setEidStatus(authProcessData.isTestIdentity()
+ ? EidIdentityStatusLevelValues.TESTIDENTITY
+ : EidIdentityStatusLevelValues.IDENTITY);
+
return authData;
}
@Override
- protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq)
+ protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq)
throws EaafException {
if (authData instanceof EidAuthenticationData) {
- ((EidAuthenticationData)authData).setGenericData(
- ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME,
+ ((EidAuthenticationData) authData).setGenericData(
+ ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME,
pendingReq.getUniquePiiTransactionIdentifier());
log.trace("Inject piiTransactionId: {} into AuthData", pendingReq.getUniquePiiTransactionIdentifier());
-
+
// set specific informations
- ((EidAuthenticationData)authData).setSsoSessionValidTo(
+ ((EidAuthenticationData) authData).setSsoSessionValidTo(
Instant.now().plusSeconds(MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60));
- //set E-ID status-level
+ // set E-ID status-level
final EidAuthProcessDataWrapper authProcessData =
- pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
- ((EidAuthenticationData)authData).setEidStatus(authProcessData.isTestIdentity()
- ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY);
-
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
+ ((EidAuthenticationData) authData).setEidStatus(authProcessData.isTestIdentity()
+ ? EidIdentityStatusLevelValues.TESTIDENTITY
+ : EidIdentityStatusLevelValues.IDENTITY);
+
+ // forward all requested IDA attributes into authData
+ forwardAllRequestedIdaAttributes(authProcessData, (EidAuthenticationData) authData,
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class)
+ .getRequestedAttributes());
+
+ // build specific bPK attribute
+ buildNatPersonInfos((EidAuthenticationData) authData, authProcessData);
+
+ // handle mandate informations
+ buildMandateInformation((EidAuthenticationData) authData, authProcessData);
+
} else {
- throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "
+ throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "
+ authData.getClass().getName());
-
+
}
-
+
}
@Override
@@ -121,4 +138,120 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder
}
+ protected String customizeLegalPersonSourcePin(String sourcePin, String sourcePinType) {
+ log.trace("Use legal-person sourcePin as it is");
+ return sourcePin;
+
+ }
+
+ protected String customizeBpkAttribute(String pvpBpkAttrValue) {
+ log.trace("Use natural-person bPK as it is");
+ return pvpBpkAttrValue;
+
+ }
+
+ private void forwardAllRequestedIdaAttributes(EidAuthProcessDataWrapper authProcessData,
+ EidAuthenticationData authData, Set<String> requestedIdaAttributes) {
+ if (requestedIdaAttributes != null && !requestedIdaAttributes.isEmpty()) {
+ log.trace("Forwarding IDA requested attributes ... ");
+ authProcessData.getGenericSessionDataStream()
+ .filter(el -> requestedIdaAttributes.contains(el.getKey()))
+ .forEach(el -> {
+ try {
+ authData.setGenericData(el.getKey(), el.getValue());
+
+ } catch (final EaafStorageException e) {
+ log.error("Can not store attribute: {} into session.", el.getKey(), e);
+ throw new RuntimeException(e);
+
+ }
+ });
+ } else {
+ log.trace("No IDA requested attributes to forwarding. Nothing todo");
+
+ }
+ }
+
+ private void buildMandateInformation(EidAuthenticationData authData,
+ EidAuthProcessDataWrapper authProcessData) throws EaafAuthenticationException, EaafBuilderException,
+ EaafStorageException {
+ authData.setUseMandate(authProcessData.isMandateUsed());
+ if (authProcessData.isMandateUsed()) {
+ log.debug("Build mandate-releated authentication data ... ");
+ if (authProcessData.isForeigner()) {
+ buildMandateInformationForEidasIncoming();
+
+ } else {
+ buildMandateInformationForEidasOutgoing(authData, authProcessData);
+
+ }
+ }
+ }
+
+ private void buildMandateInformationForEidasIncoming() {
+ log.debug("Find eIDAS incoming process. Generated mandate-information for ID-Austria system ... ");
+
+ // TODO: implement IDA specific processing of foreign mandate
+
+ }
+
+ private void buildNatPersonInfos(EidAuthenticationData authData,
+ EidAuthProcessDataWrapper authProcessData) throws EaafStorageException {
+ // clean-up BPK attribute and forward it as new property
+ authData.setGenericData(PvpAttributeDefinitions.BPK_NAME,
+ customizeBpkAttribute(authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.BPK_NAME, String.class)));
+
+ }
+
+ private void buildMandateInformationForEidasOutgoing(EidAuthenticationData authData,
+ EidAuthProcessDataWrapper authProcessData) throws EaafAuthenticationException, EaafBuilderException,
+ EaafStorageException {
+ log.debug("Find eIDAS outgoing process. Generated mandate-information for other country ... ");
+ if (authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME) != null) {
+ final Optional<Triple<String, String, Boolean>> missingAttribute =
+ MsEidasNodeConstants.DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES.stream()
+ .filter(el -> authProcessData.getGenericDataFromSession(el.getFirst()) == null)
+ .findFirst();
+ if (missingAttribute.isPresent()) {
+ log.error("ID-Austria response contains not all attributes for nat. person mandator. Missing: {}",
+ missingAttribute.get().getFirst());
+ throw new EaafAuthenticationException(ERROR_B11, new Object[] { "Nat. person mandate" });
+
+ } else {
+ log.trace("Find nat. person mandate. Mandate can be used as it is ");
+ authData.setGenericData(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME,
+ customizeBpkAttribute(authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, String.class)));
+
+ }
+
+ } else {
+ final Optional<Triple<String, String, Boolean>> missingAttribute =
+ MsEidasNodeConstants.DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES.stream()
+ .filter(el -> authProcessData.getGenericDataFromSession(el.getFirst()) == null)
+ .findFirst();
+ if (missingAttribute.isPresent()) {
+ log.error("ID-Austria response contains not all attributes for legal. person mandator. Missing: {}",
+ missingAttribute.get().getFirst());
+ throw new EaafAuthenticationException(ERROR_B11, new Object[] { "Legal. person mandate" });
+
+ } else {
+ log.trace(
+ "Find jur. person mandate. Generate eIDAS identifier from legal-person sourcePin and type ... ");
+ final String sourcePin = authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class);
+ final String sourcePinType = authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class);
+
+ // customize attribute-value for source-pin
+ final String sourcePinToUse = customizeLegalPersonSourcePin(sourcePin, sourcePinType);
+ log.debug("Use legal-person eIDAS identifer: {} from baseId: {} and baseIdType: {}",
+ sourcePinToUse, sourcePin, sourcePinType);
+ authData.setGenericData(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinToUse);
+
+ }
+ }
+ }
}
diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java
index 416a4cb5..3f4b9537 100644
--- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java
+++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java
@@ -44,6 +44,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class StatusMessageProvider implements IStatusMessenger, MessageSourceAware {
+
private static final String ERROR_MESSAGES_UNAVAILABLE =
"Error messages can NOT be load from application. Only errorCode: {0} is availabe";
private static final String ERROR_NO_MESSAGE = "No errormesseage for error with number.={0}";
@@ -56,14 +57,15 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa
private static final String MSG_WARN_NO_SOURCE = "MessageCode: {} is NOT SET for locale: {}";
private static final String MSG_INFO = "Use locale: {} as default";
- private MessageSource messageSource;
-
// external error codes
private static final String DEFAULT_EXTERNALERROR_RESOURCES = "properties/external_statuscodes_map";
private static final Locale DEFAULT_EXTERNALERROR_LOCALES = new Locale("en", "GB");
private ResourceBundle externalError = null;
+ //internal messanges
+ private MessageSource messageSource;
+
@Override
public String getMessageWithoutDefault(final String messageId, final Object[] parameters) {
if (messageSource == null) {
@@ -86,6 +88,7 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa
}
+
} catch (final MissingResourceException e2) {
log.warn("No message source", e2);
@@ -101,6 +104,7 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa
if (messageSource == null) {
return MessageFormat.format(ERROR_MESSAGES_UNAVAILABLE, new Object[]{messageId});
+
} else {
try {
final Locale locale = LocaleContextHolder.getLocale();
@@ -124,7 +128,7 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa
}
}
}
-
+
@Override
public String getResponseErrorCode(Throwable throwable) {
if (throwable instanceof EaafException) {
diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java
index 5a59a4e0..44547d95 100644
--- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java
+++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java
@@ -63,7 +63,7 @@ public class EidasCacheTransactionStoreDecorator implements ITransactionStorage,
}
- } catch (final EaafException e) {
+ } catch (final Exception e) {
log.warn("Montioring: Can not read/write to storage.", e);
return Health.down().down(e).build();
diff --git a/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml b/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml
index ee67d712..af3594a5 100644
--- a/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml
+++ b/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml
@@ -23,9 +23,6 @@
<bean id="AuthenticationManager"
class="at.asitplus.eidas.specific.core.auth.AuthenticationManager" />
- <bean id="AuthenticationDataBuilder"
- class="at.asitplus.eidas.specific.core.builder.AuthenticationDataBuilder" />
-
<bean id="eaafProtocolAuthenticationService"
class="at.gv.egiz.eaaf.core.impl.idp.auth.services.ProtocolAuthenticationService">
<property name="guiBuilder" ref="mvcGUIBuilderImpl" />
diff --git a/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java b/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java
index 12936a59..8b2eebd4 100644
--- a/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java
+++ b/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java
@@ -1,6 +1,9 @@
package at.asitplus.eidas.specific.core.test.utils;
import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.security.PublicKey;
@@ -30,8 +33,11 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.w3c.dom.Element;
+import com.google.common.collect.Sets;
+
import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
import at.asitplus.eidas.specific.core.builder.AuthenticationDataBuilder;
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
@@ -49,9 +55,9 @@ import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData;
import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
import at.gv.egiz.eaaf.core.impl.idp.auth.data.EidAuthProcessDataWrapper;
import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser;
-import at.gv.egiz.eaaf.core.impl.idp.module.test.DummySpConfiguration;
import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import lombok.SneakyThrows;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@RunWith(SpringJUnit4ClassRunner.class)
@@ -71,7 +77,8 @@ public class AuthenticationDataBuilderTest {
private MockHttpServletResponse httpResp;
private TestRequestImpl pendingReq;
- private DummySpConfiguration oaParam;
+ private Map<String, String> spConfig;
+ private ServiceProviderConfiguration oaParam;
private String eidasBind;
private String authBlock;
@@ -86,18 +93,20 @@ public class AuthenticationDataBuilderTest {
}
@Before
+ @SneakyThrows
public void initialize() throws EaafStorageException {
httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
httpResp = new MockHttpServletResponse();
RequestContextHolder.resetRequestAttributes();
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
- final Map<String, String> spConfig = new HashMap<>();
+ spConfig = new HashMap<>();
spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp");
spConfig.put("target", "urn:publicid:gv.at:cdid+XX");
spConfig.put(PROP_CONFIG_SP_NEW_EID_MODE, "true");
- oaParam = new DummySpConfiguration(spConfig, basicConfig);
-
+ oaParam = new ServiceProviderConfiguration(spConfig, basicConfig);
+ oaParam.setBpkTargetIdentifier("urn:publicid:gv.at:cdid+XX");
+
pendingReq = new TestRequestImpl();
pendingReq.setAuthUrl("https://localhost/ms_connector");
pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10));
@@ -120,6 +129,260 @@ public class AuthenticationDataBuilderTest {
}
@Test
+ public void eidasProxyModeWithJurMandate() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String commonMandate = RandomStringUtils.randomAlphabetic(10);
+
+ // set constant country-code and sourcePin to check hashed eIDAS identifier
+ String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE");
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,
+ EaafConstants.URN_PREFIX_BASEID + "+XFN");
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME));
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithJurMandateMissingAttribute() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ // set constant country-code and sourcePin to check hashed eIDAS identifier
+ String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE");
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,
+ EaafConstants.URN_PREFIX_BASEID + "+XFN");
+
+ // execute test
+ // execute test
+ EaafAuthenticationException error = assertThrows(EaafAuthenticationException.class,
+ () -> authenticationDataBuilder.buildAuthenticationData(pendingReq));
+ Assert.assertEquals("wrong errorId", "builder.11", error.getErrorId());
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandate() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String givenNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:" + bpkMandate);
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME));
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:" + bpkMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandateWrongBpkFormat() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String givenNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME));
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandateMissingAttribute() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ // execute test
+ EaafAuthenticationException error = assertThrows(EaafAuthenticationException.class,
+ () -> authenticationDataBuilder.buildAuthenticationData(pendingReq));
+ Assert.assertEquals("wrong errorId", "builder.11", error.getErrorId());
+
+ }
+
+
+
+ @Test
+ @SneakyThrows
+ public void eidasProxyMode() throws EaafAuthenticationException {
+ // initialize state
+ pendingReq = new TestRequestImpl();
+ pendingReq.setAuthUrl("https://localhost/ms_connector");
+ pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setPiiTransactionId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setSpConfig(oaParam);
+ boolean isTestIdentity = RandomUtils.nextBoolean();
+
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false);
+
+ String bpk = RandomStringUtils.randomAlphanumeric(10);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.BPK_NAME, "eidas+AT+XX:" + bpk);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ "http://eidas.europa.eu/LoA/high");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME,
+ RandomStringUtils.randomAlphabetic(2));
+
+ String randAttr = RandomStringUtils.randomAlphabetic(10);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ randAttr, RandomStringUtils.randomAlphabetic(10));
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(randAttr,
+ PvpAttributeDefinitions.BPK_NAME,
+ PvpAttributeDefinitions.GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.PRINCIPAL_NAME_NAME,
+ PvpAttributeDefinitions.BIRTHDATE_NAME,
+ PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME));
+
+
+ // execute
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ Assert.assertNull("authBlock null", authData.getGenericData(MsEidasNodeConstants.AUTH_DATA_SZR_AUTHBLOCK, String.class));
+ Assert.assertNull("eidasBind null", authData.getGenericData(MsEidasNodeConstants.AUTH_DATA_EIDAS_BIND, String.class));
+ Assert.assertNotNull("LoA null", authData.getEidasQaaLevel());
+
+ Assert.assertEquals("FamilyName", "Mustermann", authData.getFamilyName());
+ Assert.assertEquals("GivenName", "Max", authData.getGivenName());
+ Assert.assertEquals("DateOfBirth", "1940-01-01", authData.getDateOfBirth());
+
+ Assert.assertEquals("LoA", "http://eidas.europa.eu/LoA/high", authData.getEidasQaaLevel());
+ Assert.assertEquals("EID-ISSUING-NATION",
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getGenericDataFromSession(
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME),
+ authData.getCiticenCountryCode());
+
+ checkGenericAttribute(authData, PvpAttributeDefinitions.BPK_NAME, "eidas+AT+XX:" + bpk);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+
+ Assert.assertEquals("random optional attr.",
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getGenericDataFromSession(
+ randAttr),
+ authData.getGenericData(randAttr, String.class));
+
+ }
+
+
+
+ @Test
public void eidMode() throws EaafAuthenticationException {
// initialize state
boolean isTestIdentity = RandomUtils.nextBoolean();
@@ -207,10 +470,48 @@ public class AuthenticationDataBuilderTest {
authData.getBpk());
Assert.assertEquals("bPKType", EaafConstants.URN_PREFIX_CDID + "XX", authData.getBpkType());
Assert.assertNotNull("IDL", authData.getIdentityLink());
+
+ }
+
+ private void injectRepresentativeInfosIntoSession() throws EaafStorageException {
+ boolean isTestIdentity = RandomUtils.nextBoolean();
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class).setTestIdentity(isTestIdentity);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+ String givenName = RandomStringUtils.randomAlphabetic(10);
+ String familyName = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirth = "1956-12-08";
+ String bpk = RandomStringUtils.randomAlphanumeric(10);
+ String cc = pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
+ String spC = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + cc + "+" + spC);
+
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.GIVEN_NAME_NAME, givenName);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, familyName);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.BIRTHDATE_NAME, dateOfBirth);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.BPK_NAME, bpk);
+
+ //set LoA level attribute instead of explicit session-data
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getQaaLevel());
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setQaaLevel(null);
}
+
+ private void checkGenericAttribute(IAuthData authData, String attrName, String expected) {
+ assertEquals("Wrong: " + attrName, expected, authData.getGenericData(attrName, String.class));
+
+ }
+
private IIdentityLink buildDummyIdl() {
return new IIdentityLink() {
diff --git a/modules/core_commons_eidas/checks/spotbugs-exclude.xml b/modules/core_commons_eidas/checks/spotbugs-exclude.xml
new file mode 100644
index 00000000..bcb1402f
--- /dev/null
+++ b/modules/core_commons_eidas/checks/spotbugs-exclude.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<FindBugsFilter>
+ <Match>
+ <!-- File path is only loaded from configuration -->
+ <Class name="at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry" />
+ <Method name="initialize" />
+ <Bug pattern="PATH_TRAVERSAL_IN" />
+ </Match>
+</FindBugsFilter>
diff --git a/modules/core_commons_eidas/pom.xml b/modules/core_commons_eidas/pom.xml
new file mode 100644
index 00000000..56ee1555
--- /dev/null
+++ b/modules/core_commons_eidas/pom.xml
@@ -0,0 +1,174 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>modules</artifactId>
+ <version>1.3.3-SNAPSHOT</version>
+ </parent>
+ <artifactId>core_commons_eidas</artifactId>
+ <name>Commons for eIDAS Node communication</name>
+
+ <profiles>
+ <profile>
+ <id>default</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <repositories>
+ <repository>
+ <id>egiz-commons</id>
+ <url>https://apps.egiz.gv.at/maven/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ </repository>
+ <repository>
+ <id>eIDASNode-local</id>
+ <name>local</name>
+ <url>file:${basedir}/../../repository</url>
+ </repository>
+ </repositories>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>at.gv.egiz.components</groupId>
+ <artifactId>egiz-spring-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ </dependency>
+
+ <!-- eIDAS reference implemenation libs -->
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-commons</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <groupId>org.slf4j</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-specific-communication-definition</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite-specific-communication</artifactId>
+ </dependency>
+
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_core_utils</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>target/generated-sources/cxf</directory>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ <version>${spotbugs-maven-plugin.version}</version>
+ <configuration>
+ <excludeFilterFile>checks/spotbugs-exclude.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>post-unit-check</id>
+ <phase>test</phase>
+ <goals>
+ <goal>check</goal>
+ <goal>report</goal>
+ </goals>
+ <configuration>
+ <haltOnFailure>true</haltOnFailure>
+ <excludes />
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- enable co-existence of testng and junit -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <threadCount>1</threadCount>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+
+
+</project> \ No newline at end of file
diff --git a/modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/EidasConstants.java b/modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/EidasConstants.java
new file mode 100644
index 00000000..ac17c30f
--- /dev/null
+++ b/modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/EidasConstants.java
@@ -0,0 +1,85 @@
+package at.asitplus.eidas.specific.modules.core.eidas;
+
+/**
+ * Constants to communicate with eIDAS Node.
+ *
+ * @author tlenz
+ *
+ */
+public class EidasConstants {
+
+ // common config ore-fixes
+ public static final String CONIG_PROPS_EIDAS_PREFIX = "auth.eIDAS";
+ public static final String CONIG_PROPS_EIDAS_NODE = EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".node_v2";
+
+ public static final String CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL =
+ EidasConstants.CONIG_PROPS_EIDAS_NODE + ".forward.endpoint";
+ public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD =
+ EidasConstants.CONIG_PROPS_EIDAS_NODE + ".forward.method";
+
+ public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE =
+ CONIG_PROPS_EIDAS_NODE + ".countrycode";
+
+
+ // templates for post-binding forwarding
+ public static final String TEMPLATE_POST_FORWARD_NAME = "eidas_node_forward.html";
+ public static final String TEMPLATE_POST_FORWARD_ENDPOINT = "endPoint";
+ public static final String TEMPLATE_POST_FORWARD_TOKEN_NAME = "tokenName";
+ public static final String TEMPLATE_POST_FORWARD_TOKEN_VALUE = "tokenValue";
+
+
+ // common default values
+ public static final String FORWARD_METHOD_POST = "POST";
+ public static final String FORWARD_METHOD_GET = "GET";
+ public static final String DEFAULT_MS_NODE_COUNTRY_CODE = "AT";
+
+
+ // SAML2 Constants
+ public static final String SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success";
+ public static final String ERROR_URI = "urn:oasis:names:tc:SAML:2.0:status:Responder";
+
+
+ // eIDAS attribute names
+ public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier";
+ public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth";
+ public static final String eIDAS_ATTR_CURRENTGIVENNAME = "FirstName";
+ public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName";
+ public static final String eIDAS_ATTR_PLACEOFBIRTH = "PlaceOfBirth";
+ public static final String eIDAS_ATTR_BIRTHNAME = "BirthName";
+ public static final String eIDAS_ATTR_CURRENTADDRESS = "CurrentAddress";
+
+ //TODO: set parameter if it's defined
+ public static final String eIDAS_ATTR_TAXREFERENCE = "notYetDefined";
+
+ public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier";
+ public static final String eIDAS_ATTR_LEGALNAME = "LegalName";
+
+ public static final String eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER = "RepresentativePersonIdentifier";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH = "RepresentativeDateOfBirth";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME = "RepresentativeFirstName";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME = "RepresentativeFamilyName";
+
+ //eIDAS attribute URN
+ public static final String eIDAS_ATTRURN_PREFIX = "http://eidas.europa.eu/attributes/";
+ public static final String eIDAS_ATTRURN_PREFIX_NATURAL = eIDAS_ATTRURN_PREFIX + "naturalperson/";
+
+ public static final String eIDAS_ATTRURN_PERSONALIDENTIFIER =
+ eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PERSONALIDENTIFIER;
+ public static final String eIDAS_ATTRURN_CURRENTGIVENNAME =
+ eIDAS_ATTRURN_PREFIX_NATURAL + "CurrentGivenName";
+ public static final String eIDAS_ATTRURN_CURRENTFAMILYNAME =
+ eIDAS_ATTRURN_PREFIX_NATURAL + "CurrentFamilyName";
+ public static final String eIDAS_ATTRURN_DATEOFBIRTH =
+ eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_DATEOFBIRTH;
+ public static final String eIDAS_ATTRURN_PLACEOFBIRTH =
+ eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PLACEOFBIRTH;
+ public static final String eIDAS_ATTRURN_BIRTHNAME =
+ eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_BIRTHNAME;
+
+
+
+ private EidasConstants() {
+ // hide Constructor for class with static content only.
+ }
+
+}
diff --git a/modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/service/EidasAttributeRegistry.java b/modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/service/EidasAttributeRegistry.java
new file mode 100644
index 00000000..9af4e7ee
--- /dev/null
+++ b/modules/core_commons_eidas/src/main/java/at/asitplus/eidas/specific/modules/core/eidas/service/EidasAttributeRegistry.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, 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 "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "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.asitplus.eidas.specific.modules.core.eidas.service;
+
+import java.io.File;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import eu.eidas.auth.commons.attribute.AttributeRegistries;
+import eu.eidas.auth.commons.attribute.AttributeRegistry;
+import lombok.extern.slf4j.Slf4j;
+
+@Service("attributeRegistry")
+@Slf4j
+public class EidasAttributeRegistry {
+
+ private AttributeRegistry coreAttributeRegistry;
+
+ private String eidasAttributesFile;
+ private String additionalAttributesFile;
+
+ @PostConstruct
+ private void initialize() throws RuntimeException {
+ try {
+ if (eidasAttributesFile.isEmpty()) {
+ log.error("Basic eIDAS addribute definition NOT defined");
+ throw new EaafConfigurationException("config.30",
+ new Object[] { "eidas-attributes.xml" });
+
+ }
+
+ boolean additionalAttrAvailabe = false;
+ if (!additionalAttributesFile.isEmpty()) {
+ final File file = new File(additionalAttributesFile);
+ if (file.exists()) {
+ additionalAttrAvailabe = true;
+ }
+
+ }
+
+ if (!additionalAttrAvailabe) {
+ log.info("Start eIDAS ref. impl. Core without additional eIDAS attribute definitions ... ");
+ coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null);
+
+ } else {
+ // load attribute definitions
+ log.info("Start eIDAS ref. impl. Core with additional eIDAS attribute definitions ... ");
+ coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null,
+ additionalAttributesFile);
+
+ }
+
+ } catch (final Throwable e) {
+ log.error("Can NOT initialize eIDAS attribute definition.", e);
+ throw new RuntimeException("Can NOT initialize eIDAS attribute definition.", e);
+
+ }
+ }
+
+ public AttributeRegistry getCoreAttributeRegistry() {
+ return coreAttributeRegistry;
+ }
+
+
+ public void setEidasAttributesFile(String eidasAttributesFile) {
+ this.eidasAttributesFile = eidasAttributesFile;
+ }
+
+ public void setAdditionalAttributesFile(String additionalAttributesFile) {
+ this.additionalAttributesFile = additionalAttributesFile;
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth_ref_impl_config.beans.xml b/modules/core_commons_eidas/src/main/resources/eidas_v2_auth_ref_impl_config.beans.xml
index cde9687e..cde9687e 100644
--- a/modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth_ref_impl_config.beans.xml
+++ b/modules/core_commons_eidas/src/main/resources/eidas_v2_auth_ref_impl_config.beans.xml
diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummySpecificCommunicationService.java b/modules/core_commons_eidas/src/test/java/at/asitplus/eidas/specific/modules/core/eidas/test/dummy/DummySpecificCommunicationService.java
index d2b0c1ae..97ccade4 100644
--- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummySpecificCommunicationService.java
+++ b/modules/core_commons_eidas/src/test/java/at/asitplus/eidas/specific/modules/core/eidas/test/dummy/DummySpecificCommunicationService.java
@@ -1,4 +1,4 @@
-package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy;
+package at.asitplus.eidas.specific.modules.core.eidas.test.dummy;
import java.util.Collection;
@@ -9,12 +9,16 @@ import eu.eidas.auth.commons.tx.BinaryLightToken;
import eu.eidas.specificcommunication.BinaryLightTokenHelper;
import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+import lombok.Setter;
public class DummySpecificCommunicationService implements SpecificCommunicationService {
private ILightRequest lightRequest;
private ILightResponse lightResponse;
+ @Setter
+ private SpecificCommunicationException error;
+
@Override
public BinaryLightToken putRequest(ILightRequest lightRequest) throws SpecificCommunicationException {
this.lightRequest = lightRequest;
@@ -24,6 +28,10 @@ public class DummySpecificCommunicationService implements SpecificCommunicationS
@Override
public ILightRequest getAndRemoveRequest(String tokenBase64, Collection<AttributeDefinition<?>> registry)
throws SpecificCommunicationException {
+ if (error != null) {
+ throw error;
+
+ }
return lightRequest;
}
diff --git a/modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml b/modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml
new file mode 100644
index 00000000..22dbaa13
--- /dev/null
+++ b/modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<FindBugsFilter>
+ <Match>
+ <!-- CSRF protection is implicit available by request token from eIDAS Node and tokens only be logged on trace level -->
+ <Class name="at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController" />
+ <Method name="receiveEidasAuthnRequest" />
+ <OR>
+ <Bug pattern="SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING" />
+ <Bug pattern="CRLF_INJECTION_LOGS" />
+ </OR>
+ </Match>
+ <Match>
+ <!-- Redirect-URL is set by configuration only. Therefore it's trusted -->
+ <Class name="at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction" />
+ <Method name="forwardToEidasProxy" />
+ <OR>
+ <Bug pattern="UNVALIDATED_REDIRECT" />
+ </OR>
+ </Match>
+ <Match>
+ <!-- That elements are accessible by design -->
+ <OR>
+ <Class name="at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.AttrMappingElement" />
+ <Class name="at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry" />
+ </OR>
+ <OR>
+ <Bug pattern="EI_EXPOSE_REP" />
+ <Bug pattern="EI_EXPOSE_REP2" />
+ </OR>
+ </Match>
+</FindBugsFilter>
diff --git a/modules/eidas_proxy-sevice/pom.xml b/modules/eidas_proxy-sevice/pom.xml
new file mode 100644
index 00000000..d8ab9dee
--- /dev/null
+++ b/modules/eidas_proxy-sevice/pom.xml
@@ -0,0 +1,193 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>modules</artifactId>
+ <version>1.3.3-SNAPSHOT</version>
+ </parent>
+ <groupId>at.asitplus.eidas.ms_specific.modules</groupId>
+ <artifactId>eidas_proxy-sevice</artifactId>
+ <name>eIDAS specific proxy-service</name>
+ <description>Austrian specific eIDAS Proxy-Service to handle eIDAS Proxy-Service requests from other member states</description>
+
+ <repositories>
+ <repository>
+ <id>eIDASNode-local</id>
+ <name>local</name>
+ <url>file:${basedir}/../../repository</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>at.gv.egiz.components</groupId>
+ <artifactId>egiz-spring-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_commons_eidas</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_sp</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-light-commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-specific-communication-definition</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-jcache-ignite-specific-communication</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_common_lib</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific</groupId>
+ <artifactId>core_commons_eidas</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <!-- dependency>
+ <groupId>at.asitplus.eidas.ms_specific.modules</groupId>
+ <artifactId>authmodule-eIDAS-v2</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>-->
+
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_core_utils</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ </dependencies>
+
+<build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ <version>${spotbugs-maven-plugin.version}</version>
+ <configuration>
+ <excludeFilterFile>checks/spotbugs-exclude.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>post-unit-check</id>
+ <phase>test</phase>
+ <goals>
+ <goal>check</goal>
+ <goal>report</goal>
+ </goals>
+ <configuration>
+ <haltOnFailure>true</haltOnFailure>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- enable co-existence of testng and junit -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <threadCount>1</threadCount>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java
new file mode 100644
index 00000000..23390da8
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/EidasProxyMessageSource.java
@@ -0,0 +1,22 @@
+package at.asitplus.eidas.specific.modules.msproxyservice;
+
+import java.util.Arrays;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;
+
+/**
+ * i18n Message-Source for eIDAS Proxy-Service messages.
+ *
+ * @author tlenz
+ *
+ */
+public class EidasProxyMessageSource implements IMessageSourceLocation {
+
+ @Override
+ public List<String> getMessageSourceLocation() {
+ return Arrays.asList("classpath:messages/eidasproxy_messages");
+
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java
new file mode 100644
index 00000000..a2a2e78f
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java
@@ -0,0 +1,59 @@
+package at.asitplus.eidas.specific.modules.msproxyservice;
+
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+
+/**
+ * Constants for MS-specific eIDAS Proxy-Service.
+ *
+ * @author tlenz
+ *
+ */
+public class MsProxyServiceConstants {
+
+ // general constants
+ public static final String TEMPLATE_SP_UNIQUE_ID = "eidasProxyAuth_from_{0}_type_{1}";
+
+ // configuration constants
+ public static final String CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID = EidasConstants.CONIG_PROPS_EIDAS_NODE
+ + ".proxy.entityId";
+ public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = EidasConstants.CONIG_PROPS_EIDAS_NODE
+ + ".proxy.forward.endpoint";
+
+
+ public static final String CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.attribute.mapping.config";
+
+
+ // mandate configuration
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.enabled";
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.natural.default";
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.legal.default";
+
+
+ public static final String CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON =
+ EidasConstants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.workaround.mandates.legalperson";
+
+ // specific eIDAS-Connector configuration
+ public static final String CONIG_PROPS_CONNECTOR_PREFIX = "connector";
+ public static final String CONIG_PROPS_CONNECTOR_UNIQUEID = EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER;
+ public static final String CONIG_PROPS_CONNECTOR_COUNTRYCODE = "countryCode";
+ public static final String CONIG_PROPS_CONNECTOR_MANDATES_ENABLED = "mandates.enabled";
+ public static final String CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL = "mandates.natural";
+ public static final String CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL = "mandates.legal";
+ public static final String CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS = "validation.attributes.mds";
+
+
+ //http end-points
+ public static final String EIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/light/idp/post";
+ public static final String EIDAS_HTTP_ENDPOINT_IDP_REDIRECT = "/eidas/light/idp/redirect";
+
+ private MsProxyServiceConstants() {
+ //private constructor for class with only constant values
+
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java
new file mode 100644
index 00000000..571ad8ab
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceSpringResourceProvider.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, 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 "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "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.asitplus.eidas.specific.modules.msproxyservice;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class MsProxyServiceSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public String getName() {
+ return "MS-specific eIDAS Proxy-Service module";
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ return null;
+
+ }
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ final ClassPathResource eidasProxyServiceConfig =
+ new ClassPathResource("/spring/eidas_proxy-service.beans.xml", MsProxyServiceSpringResourceProvider.class);
+ final ClassPathResource eidasRefImplConfig = new ClassPathResource("/eidas_v2_auth_ref_impl_config.beans.xml",
+ MsProxyServiceSpringResourceProvider.class);
+
+
+ return new Resource[] { eidasProxyServiceConfig, eidasRefImplConfig };
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java
new file mode 100644
index 00000000..2dffbc2d
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/AttrMappingElement.java
@@ -0,0 +1,49 @@
+
+package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import lombok.Data;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "eidasAttribute",
+ "idaAttribute",
+ "addionalRequiredAttributes",
+ "specificAttributeHandlerClass",
+ "type"
+})
+@Data
+public class AttrMappingElement {
+
+ /**
+ * eIDAS specific attribute name.
+ */
+ @JsonProperty("eidasAttribute")
+ private String eidasAttributeName;
+
+ /**
+ * IDA specific attribute name.
+ */
+ @JsonProperty("idaAttribute")
+ private IdaAttribute idaAttribute;
+
+
+ @JsonProperty("addionalRequiredAttributes")
+ private List<String> addionalRequiredAttributes;
+
+
+ @JsonProperty("specificAttributeHandlerClass")
+ private String specificAttributeHandlerClass;
+
+ /**
+ * attribute characteristics.
+ */
+ @JsonProperty("type")
+ private Type type;
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java
new file mode 100644
index 00000000..ee5fc810
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/IdaAttribute.java
@@ -0,0 +1,29 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import lombok.Data;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "basic",
+ "withMandates"
+})
+@Data
+public class IdaAttribute {
+
+ /**
+ * IDA attribute name, in case of simple process without mandates.
+ */
+ @JsonProperty("basic")
+ private String basic;
+
+ /**
+ * IDA attribute name, in case of mandate process.
+ */
+ @JsonProperty("withMandates")
+ private String withMandates;
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java
new file mode 100644
index 00000000..6a06a5b5
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/dto/attributes/Type.java
@@ -0,0 +1,91 @@
+
+package at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import lombok.Data;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "mds",
+ "autoIncludeWithMandates",
+ "mandator"
+})
+@Data
+public class Type {
+
+ /**
+ * <code>true</code> if this attribute is part of MDS, otherwise <code>false</code>.
+ */
+ @JsonProperty("mds")
+ private Boolean mds;
+
+ /**
+ * <code>true</code> if that attribute has to be included into eIDAS response in case of mandates.
+ */
+ @JsonProperty("autoIncludeWithMandates")
+ private Boolean autoIncludeWithMandates;
+
+ /**
+ * Classifie that attribute to specific mandate modes.
+ */
+ @JsonProperty("mandator")
+ private Type.Mandator mandator;
+
+ /**
+ * Mandate type in case of a mandate attriute.
+ */
+ public enum Mandator {
+ BOTH("both"),
+ LEGAL("legal"),
+ NATURAL("natural"),
+ NONE("none");
+
+ private final String value;
+ private static final Map<String, Type.Mandator> CONSTANTS = new HashMap<>();
+
+ static {
+ for (final Type.Mandator c : values()) {
+ CONSTANTS.put(c.value, c);
+ }
+ }
+
+ Mandator(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return this.value;
+ }
+
+ @JsonValue
+ public String value() {
+ return this.value;
+ }
+
+ /**
+ * Build {@link Mandator} from textual representation.
+ *
+ * @param value textual representation
+ * @return Type of the mandator
+ */
+ @JsonCreator
+ public static Type.Mandator fromValue(String value) {
+ final Type.Mandator constant = CONSTANTS.get(value);
+ if (constant == null) {
+ throw new IllegalArgumentException(value);
+ } else {
+ return constant;
+ }
+ }
+
+ }
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java
new file mode 100644
index 00000000..43592a28
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/exception/EidasProxyServiceException.java
@@ -0,0 +1,19 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.exception;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+
+public class EidasProxyServiceException extends EaafException {
+
+ private static final long serialVersionUID = 1L;
+
+ public EidasProxyServiceException(String errorId, Object[] params) {
+ super(errorId, params);
+
+ }
+
+ public EidasProxyServiceException(String errorId, Object[] params, Throwable e) {
+ super(errorId, params, e);
+
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java
new file mode 100644
index 00000000..6a5e4967
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java
@@ -0,0 +1,138 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.handler;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IExtendedConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Attribute handling to integrate BORIS attributes without full IDA support for sector-specific attributes.
+ *
+ * <p>This attribute-handler maps a specific mandate-profile to an eIDAS attribute.</p>
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class EJusticePersonRoleHandler implements IEidasAttributeHandler {
+
+ public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.attributes.ejusticerole.mandate.profiles";
+ public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.attributes.ejusticerole.mandate.mode";
+ public static final String CONFIG_PROP_IDA_ADDITIONAL_ATTRIBUTES =
+ "advanced.attributes.ejusticerole.additional.ida.attributes";
+
+ public static final String CONFIG_PROP_RESULT_PREFIX = "advanced.attributes.ejusticerole.value";
+ public static final String CONFIG_PROP_RESULT_VALUE_DELIMITER = "=";
+
+
+ @Autowired IExtendedConfiguration config;
+
+ private SpMandateModes mandateMode;
+ private List<String> mandateProfiles;
+ private List<String> additionalReqAttributes;
+ private Map<String, String> resultMapper;
+
+ @Override
+ public void performSpConfigPostprocessing(ServiceProviderConfiguration spConfig) {
+ spConfig.setMandateMode(mandateMode);
+ spConfig.setMandateProfiles(mandateProfiles);
+ log.info("Enforcing mandate-mode: {} with profile: {}", mandateMode, mandateProfiles);
+
+ if (!additionalReqAttributes.isEmpty()) {
+ spConfig.getRequestedAttributes().addAll(additionalReqAttributes);
+ log.info("Add additional requested attributes: {}", additionalReqAttributes);
+
+ }
+
+ }
+
+ @Override
+ public String buildAttributeValue(@NonNull IEidAuthData eidAuthData) {
+ final String mandateType = eidAuthData.getGenericData(
+ PvpAttributeDefinitions.MANDATE_TYPE_NAME, String.class);
+ if (StringUtils.isNotEmpty(mandateType)) {
+ String attrValue = resultMapper.get(mandateType);
+ if (StringUtils.isNotEmpty(attrValue)) {
+ log.debug("Mapping mandate-type: {} to EJusticePersonRole: {}", mandateType, attrValue);
+ return attrValue;
+
+ } else {
+ log.info("Ignore mandate-type: {}, because it is not mapped to a EJusticePersonRole", mandateType);
+
+ }
+
+ } else {
+ log.warn("Can not build: EJusticePersonRole, because IDA response contains no attribute: ",
+ PvpAttributeDefinitions.MANDATE_TYPE_NAME);
+
+ }
+
+
+ return null;
+
+ }
+
+
+ @PostConstruct
+ private void initialize() throws EaafConfigurationException {
+ mandateMode = SpMandateModes.fromString(loadConfigValue(CONFIG_PROP_IDA_MANDATE_MODE, true));
+ mandateProfiles = KeyValueUtils.getListOfCsvValues(loadConfigValue(CONFIG_PROP_IDA_MANDATE_PROFILE, true));
+ additionalReqAttributes = KeyValueUtils.getListOfCsvValues(
+ loadConfigValue(CONFIG_PROP_IDA_ADDITIONAL_ATTRIBUTES, false));
+ resultMapper = config.getBasicConfigurationWithPrefix(CONFIG_PROP_RESULT_PREFIX).values().stream()
+ .filter(el -> el.contains(CONFIG_PROP_RESULT_VALUE_DELIMITER))
+ .collect(Collectors.toMap(x -> split(x, 0), x -> split(x, 1)));
+
+ // validate requested profiles to result map
+ Optional<String> missingConfig = mandateProfiles.stream()
+ .filter(el -> !resultMapper.containsKey(el))
+ .findFirst();
+ if (missingConfig.isPresent()) {
+ log.error("Missing mandate-profile: {} in result mapping", missingConfig.get());
+ throw new EaafConfigurationException("internal.configuration.00",
+ new Object[]{CONFIG_PROP_RESULT_PREFIX});
+
+ }
+
+ log.info("Initialize: {} with mandate-profile: {} mandate-mode: {} and result-map:",
+ EJusticePersonRoleHandler.class.getSimpleName(), mandateProfiles, mandateMode);
+ resultMapper.entrySet().stream().forEach(el ->
+ log.info("Profile: {} --> Attribute-Value: {}", el.getKey(), el.getValue()));
+
+
+ }
+
+ private String split(String value, int i) {
+ return value.split(CONFIG_PROP_RESULT_VALUE_DELIMITER, 2)[i];
+
+ }
+
+
+ private String loadConfigValue(String configProp, boolean isRequired) throws EaafConfigurationException {
+ String value = config.getBasicConfiguration(configProp);
+ if (StringUtils.isEmpty(value) && isRequired) {
+ throw new EaafConfigurationException("internal.configuration.00",
+ new Object[]{configProp});
+
+ }
+
+ return value;
+
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java
new file mode 100644
index 00000000..5a9c8d8c
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java
@@ -0,0 +1,36 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.handler;
+
+import javax.annotation.Nullable;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
+import lombok.NonNull;
+
+/**
+ * Handlers for attribute-processing that requires more features than a simple mapping.
+ *
+ * @author tlenz
+ *
+ */
+public interface IEidasAttributeHandler {
+
+ /**
+ * Perform attribute-releated post-processing of internal Service-Provider configuration.
+ *
+ * @param spConfig SP configuration that was build from incoming eIDAS Authn. request.
+ */
+ void performSpConfigPostprocessing(@NonNull ServiceProviderConfiguration spConfig);
+
+
+ /**
+ * Build eIDAS attribute-value from authentication data.
+ *
+ * @param eidAuthData Authentication data for current process
+ * @return attribute-value if attribute is available, otherwise <code>null</code>
+ */
+ @Nullable
+ String buildAttributeValue(@NonNull IEidAuthData eidAuthData);
+
+
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
new file mode 100644
index 00000000..d0e3d1ba
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
@@ -0,0 +1,524 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.protocol;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.core.StatusCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Streams;
+
+import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
+import at.asitplus.eidas.specific.modules.msproxyservice.handler.IEidasAttributeHandler;
+import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils;
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
+import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.GuiBuildException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import eu.eidas.auth.commons.EIDASSubStatusCode;
+import eu.eidas.auth.commons.EidasParameterKeys;
+import eu.eidas.auth.commons.light.ILightRequest;
+import eu.eidas.auth.commons.light.impl.LightResponse;
+import eu.eidas.auth.commons.light.impl.LightResponse.Builder;
+import eu.eidas.auth.commons.light.impl.ResponseStatus;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * End-point implementation for authentication requests from eIDAS Proxy-Service
+ * to MS-specific eIDAS Proxy-Service.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+@Controller
+public class EidasProxyServiceController extends AbstractController implements IModulInfo {
+
+ private static final String ERROR_01 = "eidas.proxyservice.01";
+ private static final String ERROR_02 = "eidas.proxyservice.02";
+ private static final String ERROR_03 = "eidas.proxyservice.03";
+ private static final String ERROR_04 = "eidas.proxyservice.04";
+ private static final String ERROR_05 = "eidas.proxyservice.05";
+ private static final String ERROR_07 = "eidas.proxyservice.07";
+ private static final String ERROR_08 = "eidas.proxyservice.08";
+ private static final String ERROR_09 = "eidas.proxyservice.09";
+ private static final String ERROR_10 = "eidas.proxyservice.10";
+ private static final String ERROR_11 = "eidas.proxyservice.11";
+
+ public static final String PROTOCOL_ID = "eidasProxy";
+
+ @Autowired
+ ProxyEidasAttributeRegistry attrRegistry;
+ @Autowired
+ ProxyServiceAuthenticationAction responseAction;
+
+ /**
+ * End-point that receives authentication requests from eIDAS Node.
+ *
+ * @param httpReq Http request
+ * @param httpResp Http response
+ * @throws IOException In case of general error
+ * @throws EaafException In case of a validation or processing error
+ */
+ @RequestMapping(value = {
+ MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_POST,
+ MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_REDIRECT
+ },
+ method = { RequestMethod.POST, RequestMethod.GET })
+ public void receiveEidasAuthnRequest(HttpServletRequest httpReq, HttpServletResponse httpResp)
+ throws IOException,
+ EaafException {
+ log.trace("Receive request on eidas proxy-service end-points");
+ ProxyServicePendingRequest pendingReq = null;
+ try {
+ // get token from Request
+ final String tokenBase64 = httpReq.getParameter(EidasParameterKeys.TOKEN.toString());
+ if (StringUtils.isEmpty(tokenBase64)) {
+ log.warn("NO eIDAS message token found.");
+ throw new EidasProxyServiceException(ERROR_02, null);
+
+ }
+ log.trace("Receive eIDAS-node token: {}. Searching authentication request from eIDAS Proxy-Service ...",
+ tokenBase64);
+
+ // read authentication request from shared cache
+ final SpecificCommunicationService specificProxyCommunicationService =
+ (SpecificCommunicationService) applicationContext.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+ final ILightRequest eidasRequest = specificProxyCommunicationService.getAndRemoveRequest(
+ tokenBase64,
+ ImmutableSortedSet.copyOf(attrRegistry.getCoreRegistry().getCoreAttributeRegistry()
+ .getAttributes()));
+ if (eidasRequest == null) {
+ log.info("Find no eIDAS Authn. Request with stated token.");
+ throw new EidasProxyServiceException(ERROR_11, null);
+
+ }
+
+ log.debug("Received eIDAS auth. request from: {}, Initializing authentication environment ... ",
+ eidasRequest.getSpCountryCode() != null ? eidasRequest.getSpCountryCode() : "'missing SP-country'");
+ log.trace("Received eIDAS requst: {}", eidasRequest);
+
+ // create pendingRequest object
+ pendingReq = applicationContext.getBean(ProxyServicePendingRequest.class);
+ pendingReq.initialize(httpReq, authConfig);
+ pendingReq.setModule(getName());
+
+ // log 'transaction created' event
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED,
+ pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP,
+ httpReq.getRemoteAddr());
+
+ // validate eIDAS Authn. request and set into pending-request
+ validateEidasAuthnRequest(eidasRequest);
+ pendingReq.setEidasRequest(eidasRequest);
+
+ // generate Service-Provider configuration from eIDAS request
+ final ISpConfiguration spConfig = generateSpConfigurationFromEidasRequest(eidasRequest);
+
+ // validate eIDAS Authn. request by using eIDAS Connector specifc parameters
+ validateEidasAuthnRequest(spConfig, eidasRequest);
+
+ // populate pendingRequest with parameters
+ pendingReq.setOnlineApplicationConfiguration(spConfig);
+ pendingReq.setSpEntityId(spConfig.getUniqueIdentifier());
+ pendingReq.setPassiv(false);
+ pendingReq.setForce(true);
+
+ // AuthnRequest needs authentication
+ pendingReq.setNeedAuthentication(true);
+
+ // set protocol action, which should be executed after authentication
+ pendingReq.setAction(ProxyServiceAuthenticationAction.class.getName());
+
+ // switch to session authentication
+ protAuthService.performAuthentication(httpReq, httpResp, pendingReq);
+
+ } catch (final EidasProxyServiceException e) {
+ throw e;
+
+ } catch (final SpecificCommunicationException e) {
+ log.error("Can not read eIDAS Authn request from shared cache. Reason: {}", e.getMessage());
+ throw new EidasProxyServiceException(ERROR_03, new Object[] { e.getMessage() }, e);
+
+ } catch (final Throwable e) {
+ // write revision log entries
+ if (pendingReq != null) {
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
+ pendingReq.getUniqueTransactionIdentifier());
+ }
+
+ throw new EidasProxyServiceException(ERROR_01, new Object[] { e.getMessage() }, e);
+ }
+
+ }
+
+ @Override
+ public boolean generateErrorMessage(Throwable e, HttpServletRequest httpReq, HttpServletResponse httpResp,
+ IRequest pendingReq) throws Throwable {
+ if (pendingReq instanceof ProxyServicePendingRequest) {
+ try {
+ final ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest();
+
+ // build eIDAS response
+ final Builder lightRespBuilder = LightResponse.builder();
+ lightRespBuilder.id(UUID.randomUUID().toString());
+ lightRespBuilder.inResponseToId(eidasReq.getId());
+ lightRespBuilder.relayState(eidasReq.getRelayState());
+ lightRespBuilder.issuer(authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID));
+ lightRespBuilder.subject(UUID.randomUUID().toString());
+ lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT);
+ lightRespBuilder.status(ResponseStatus.builder()
+ .statusCode(StatusCode.RESPONDER)
+ .subStatusCode(EIDASSubStatusCode.AUTHN_FAILED_URI.getValue())
+ .statusMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()))
+ .build());
+
+ // forward to eIDAS Proxy-Service
+ responseAction.forwardToEidasProxy(pendingReq, httpReq, httpResp, lightRespBuilder.build());
+
+ return true;
+
+ } catch (ServletException | IOException | GuiBuildException e1) {
+ log.warn("Forward error to eIDAS Proxy-Service FAILED. Handle error localy ... ", e1);
+
+ }
+
+ } else {
+ log.error("eIDAS Proxy-Service authentication requires PendingRequest of Type: {}",
+ ProxyServicePendingRequest.class.getName());
+
+ }
+
+ return false;
+
+ }
+
+ @Override
+ public String getName() {
+ return EidasProxyServiceController.class.getName();
+
+ }
+
+ @Override
+ public String getAuthProtocolIdentifier() {
+ return PROTOCOL_ID;
+
+ }
+
+ @Override
+ public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) {
+ return true;
+
+ }
+
+ /**
+ * Generic validation of incoming eIDAS request.
+ *
+ * @param eidasRequest Incoming eIDAS authentication request
+ * @throws EidasProxyServiceException In case of a validation error
+ */
+ private void validateEidasAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException {
+ if (StringUtils.isEmpty(eidasRequest.getIssuer())) {
+ throw new EidasProxyServiceException(ERROR_05, null);
+
+ }
+
+ // TODO: validate some other stuff
+
+ }
+
+ /**
+ * eIDAS Connector specific validation of incoming eIDAS request.
+ *
+ * @param eidasRequest Incoming eIDAS authentication request
+ * @param spConfig eIDAS Connector configuration
+ * @throws EidasProxyServiceException In case of a validation error
+ */
+ private void validateEidasAuthnRequest(ISpConfiguration spConfig, ILightRequest eidasRequest)
+ throws EidasProxyServiceException {
+ // check if natural-person and legal-person attributes requested in parallel
+ if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, true)
+ && EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)
+ && EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
+ throw new EidasProxyServiceException(ERROR_08, null);
+
+ }
+
+ // TODO: validate some other stuff
+
+ }
+
+ /**
+ * Generate a dummy Service-Provider configuration for processing.
+ *
+ * @param eidasRequest Incoming eIDAS authentication request
+ * @return Service-Provider configuration that can be used for authentication
+ * @throws EidasProxyServiceException In case of a configuration error
+ */
+ private ISpConfiguration generateSpConfigurationFromEidasRequest(ILightRequest eidasRequest)
+ throws EidasProxyServiceException {
+ try {
+
+ final Map<String, String> connectorConfigMap = extractRawConnectorConfiguration(eidasRequest);
+
+ // check if country-code is available
+ final String spCountry = connectorConfigMap.get(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE);
+ if (StringUtils.isEmpty(spCountry)) {
+ throw new EidasProxyServiceException(ERROR_07, null);
+
+ }
+
+ // build FriendyName from CountryCode and SPType
+ connectorConfigMap.put(MsEidasNodeConstants.PROP_CONFIG_SP_FRIENDLYNAME,
+ MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID,
+ spCountry, eidasRequest.getSpType()));
+
+ // build Service-Provider configuration object
+ final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap,
+ authConfig);
+
+ // build bPK target from Country-Code
+ final String ccCountry = authConfig.getBasicConfiguration(
+ EidasConstants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE,
+ EidasConstants.DEFAULT_MS_NODE_COUNTRY_CODE);
+ spConfig.setBpkTargetIdentifier(
+ EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry);
+
+ // set required LoA from eIDAS request
+ spConfig.setRequiredLoA(
+ eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList()));
+
+ // build mandate profiles for this specific request
+ buildMandateProfileConfiguration(spConfig, eidasRequest);
+
+ // map eIDAS attributes to national attributes
+ buildNationalRequestedAttributes(spConfig, eidasRequest);
+
+ // execute custom attribute-handler
+ advancedAttributeHandler(spConfig, eidasRequest);
+
+ return spConfig;
+
+ } catch (final EidasProxyServiceException e) {
+ throw e;
+
+ } catch (final EaafException e) {
+ throw new EidasProxyServiceException(ERROR_04, new Object[] { e.getMessage() }, e);
+
+ }
+ }
+
+ private void advancedAttributeHandler(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) {
+ Set<String> requiredHandlers = eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream()
+ .map(el -> attrRegistry.mapEidasAttributeToAttributeHandler(el.getNameUri().toString()).orElse(null))
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toSet());
+
+ if (!requiredHandlers.isEmpty()) {
+ log.info("eIDAS requested attributes requires #{} specific attribute-hander. "
+ + "Starting advanced attribute-handling ... ", requiredHandlers.size());
+ requiredHandlers.forEach(el -> executeAttributeHandler(el, spConfig));
+
+ } else {
+ log.debug("No advanced eIDAS attribute-handling required.");
+
+ }
+ }
+
+ private void executeAttributeHandler(String handlerClass, ServiceProviderConfiguration spConfig) {
+ try {
+ IEidasAttributeHandler handler = applicationContext.getBean(handlerClass, IEidasAttributeHandler.class);
+
+ log.trace("Perfom SP config post-processing by using: {}", handler.getClass().getName());
+ handler.performSpConfigPostprocessing(spConfig);
+
+ } catch (Exception e) {
+ log.error("No custom attribute-handler implementation for: {}. Operation can NOT be performed", handlerClass, e);
+
+ }
+ }
+
+ private void buildNationalRequestedAttributes(
+ ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) {
+ final boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode());
+ spConfig.setRequestedAttributes(
+ Streams.concat(
+ eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream()
+ .map(el -> attrRegistry.getIdaAttributesForEidasAttribute(
+ el.getNameUri().toString(), mandatesEnabled))
+ .flatMap(Collection::stream)
+ .filter(Objects::nonNull),
+ attrRegistry.getAlwaysRequestedAttributes(mandatesEnabled))
+ .collect(Collectors.toSet()));
+ log.debug("Inject #{} attributes to request from IDA system", spConfig.getRequestedAttributes().size());
+
+ }
+
+ private Map<String, String> extractRawConnectorConfiguration(ILightRequest eidasRequest) {
+ final Map<String, String> allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX);
+ if (log.isTraceEnabled()) {
+ log.trace("Full-connector configuration:");
+ allConnectorConfigs.entrySet().stream().forEach(
+ el -> log.trace("Key: {} -> Value: {}", el.getKey(), el.getValue()));
+
+ }
+
+ final Map<String, String> connectorConfig = allConnectorConfigs.entrySet().stream()
+ .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER)
+ && el.getValue().equals(eidasRequest.getIssuer()))
+ .findFirst()
+ .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs,
+ KeyValueUtils.getParentKey(el.getKey()) + KeyValueUtils.KEY_DELIMITER))
+ .orElse(new HashMap<>());
+
+ if (connectorConfig.isEmpty()) {
+ log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ",
+ eidasRequest.getIssuer());
+
+ // set EntityId of the requesting eIDAS Connector
+ connectorConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, eidasRequest.getIssuer());
+
+ // set country-code from eIDAS request
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE,
+ eidasRequest.getSpCountryCode());
+
+ // set default mandate configuration
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED,
+ String.valueOf(authConfig.getBasicConfigurationBoolean(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false)));
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL));
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL));
+
+ } else {
+ log.debug("Find specific configuration for eIDAS Connector: {}", eidasRequest.getIssuer());
+
+ }
+
+ return connectorConfig;
+
+ }
+
+ private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig,
+ ILightRequest eidasRequest)
+ throws EidasProxyServiceException {
+ // check if mandates are enabled
+ if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED,
+ false)) {
+ injectMandateInfosIntoSpConfig(spConfig, eidasRequest);
+
+ } else {
+ if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) {
+ throw new EidasProxyServiceException(ERROR_09, null);
+
+ }
+
+ spConfig.setMandateProfiles(Collections.emptyList());
+ spConfig.setMandateMode(SpMandateModes.NONE);
+
+ }
+
+ }
+
+ private void injectMandateInfosIntoSpConfig(ServiceProviderConfiguration spConfig,
+ ILightRequest eidasRequest) throws EidasProxyServiceException {
+ log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ",
+ spConfig.getUniqueIdentifier());
+
+ final List<String> legalPersonProfiles = KeyValueUtils.getListOfCsvValues(spConfig.getConfigurationValue(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL));
+ final List<String> natPersonProfiles = KeyValueUtils.getListOfCsvValues(spConfig.getConfigurationValue(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL));
+
+ if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)
+ && EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
+ log.debug(
+ "Find requested attributes for legal and natural persons. Injecting mandate-profiles for both ... ");
+ spConfig.setMandateProfiles(ListUtils.union(natPersonProfiles, legalPersonProfiles));
+
+ // set Mandate-Mode based on SP configuration
+ final boolean isLegalPersonProfile = !legalPersonProfiles.isEmpty();
+ final boolean isNaturalPersonProfile = !natPersonProfiles.isEmpty();
+ spConfig.setMandateMode(
+ isLegalPersonProfile && isNaturalPersonProfile
+ ? SpMandateModes.BOTH
+ : isLegalPersonProfile
+ ? SpMandateModes.LEGAL_FORCE
+ : SpMandateModes.NATURAL);
+
+ } else if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) {
+ // check if legal person is requested
+ spConfig.setMandateProfiles(legalPersonProfiles);
+ spConfig.setMandateMode(SpMandateModes.LEGAL_FORCE);
+
+ if (spConfig.getMandateProfiles().isEmpty()) {
+ throw new EidasProxyServiceException(ERROR_10, null);
+
+ }
+
+ } else if (EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
+ spConfig.setMandateProfiles(natPersonProfiles);
+ spConfig.setMandateMode(SpMandateModes.NATURAL);
+
+ }
+
+ if (spConfig.getMandateProfiles().isEmpty()) {
+ log.debug("No mandate-profiles for issure: {}. Set mandate-mode to 'none'",
+ spConfig.getUniqueIdentifier());
+ spConfig.setMandateMode(SpMandateModes.NONE);
+
+ } else {
+ log.debug("Set mandate-profiles: {} to request from issuer: {}",
+ spConfig.getMandateProfiles(), spConfig.getUniqueIdentifier());
+
+ }
+
+ }
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java
new file mode 100644
index 00000000..f1cb8f0b
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java
@@ -0,0 +1,373 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.protocol;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import at.asitplus.eidas.specific.core.gui.StaticGuiBuilderConfiguration;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
+import at.asitplus.eidas.specific.modules.msproxyservice.handler.IEidasAttributeHandler;
+import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.msproxyservice.utils.EidasProxyServiceUtils;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder;
+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.IEidAuthData;
+import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.GuiBuildException;
+import at.gv.egiz.eaaf.core.impl.data.SloInformationImpl;
+import eu.eidas.auth.commons.EidasParameterKeys;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.ILightRequest;
+import eu.eidas.auth.commons.light.ILightResponse;
+import eu.eidas.auth.commons.light.impl.LightResponse;
+import eu.eidas.auth.commons.light.impl.LightResponse.Builder;
+import eu.eidas.auth.commons.light.impl.ResponseStatus;
+import eu.eidas.auth.commons.tx.BinaryLightToken;
+import eu.eidas.specificcommunication.BinaryLightTokenHelper;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Result action of a successfully performed eIDAS Proxy-Service authentication.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class ProxyServiceAuthenticationAction implements IAction {
+
+ private static final String PROXYSERVICE_AUTH_ACTION_NAME = "MS-specific eIDAS-Proxy action";
+
+ @Autowired
+ ApplicationContext context;
+ @Autowired
+ IConfiguration basicConfig;
+ @Autowired
+ ResourceLoader resourceLoader;
+ @Autowired
+ ISpringMvcGuiFormBuilder guiBuilder;
+ @Autowired
+ ProxyEidasAttributeRegistry attrRegistry;
+
+ @Override
+ public SloInformationInterface processRequest(IRequest pendingReq, HttpServletRequest httpReq,
+ HttpServletResponse httpResp, IAuthData authData) throws EaafException {
+ if (pendingReq instanceof ProxyServicePendingRequest) {
+ try {
+ final ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest();
+
+ // build eIDAS response
+ final Builder lightRespBuilder = LightResponse.builder();
+ lightRespBuilder.id(UUID.randomUUID().toString());
+ lightRespBuilder.inResponseToId(eidasReq.getId());
+ lightRespBuilder.relayState(eidasReq.getRelayState());
+
+ lightRespBuilder.status(ResponseStatus.builder()
+ .statusCode(EidasConstants.SUCCESS_URI)
+ .build());
+
+ // TODO: check if we can use transient subjectNameIds
+ lightRespBuilder.subject(UUID.randomUUID().toString());
+ lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT);
+
+ // TODO:
+ lightRespBuilder.issuer(basicConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID));
+ lightRespBuilder.levelOfAssurance(authData.getEidasQaaLevel());
+ lightRespBuilder.attributes(buildAttributesFromAuthData(authData, eidasReq));
+
+ // set SLO response object of EAAF framework
+ final SloInformationImpl sloInformation = new SloInformationImpl();
+ sloInformation.setProtocolType(pendingReq.requestedModule());
+ sloInformation
+ .setSpEntityID(pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
+
+ // forward to eIDAS Proxy-Service
+ forwardToEidasProxy(pendingReq, httpReq, httpResp, lightRespBuilder.build());
+
+ return sloInformation;
+
+ } catch (ServletException | IOException | GuiBuildException e) {
+ throw new EidasProxyServiceException("eidas.proxyservice.06", null, e);
+
+ }
+
+ } else {
+ log.error("eIDAS Proxy-Service authentication requires PendingRequest of Type: {}",
+ ProxyServicePendingRequest.class.getName());
+ throw new EaafException("eidas.proxyservice.99");
+
+ }
+ }
+
+ @Override
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ return true;
+
+ }
+
+ @Override
+ public String getDefaultActionName() {
+ return PROXYSERVICE_AUTH_ACTION_NAME;
+
+ }
+
+ /**
+ * Forward eIDAS Light response to eIDAS node.
+ *
+ * @param pendingReq Current pending request.
+ * @param httpReq Current HTTP request
+ * @param httpResp Current HTTP response
+ * @param lightResponse eIDAS LightResponse
+ * @throws EaafConfigurationException In case of a configuration error
+ * @throws IOException In case of a general error
+ * @throws GuiBuildException In case of a GUI rendering error, if http
+ * POST binding is used
+ * @throws ServletException In case of a general error
+ */
+ public void forwardToEidasProxy(IRequest pendingReq, HttpServletRequest httpReq,
+ HttpServletResponse httpResp, LightResponse lightResponse) throws EaafConfigurationException,
+ IOException,
+ GuiBuildException, ServletException {
+
+ // put request into shared cache
+ final BinaryLightToken token = putResponseInCommunicationCache(lightResponse);
+ final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token);
+
+ // select forward URL regarding the selected environment
+ final String forwardUrl = basicConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL);
+
+ if (StringUtils.isEmpty(forwardUrl)) {
+ log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops");
+ throw new EaafConfigurationException("config.08",
+ new Object[] { MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL });
+
+ }
+ log.debug("ForwardURL: " + forwardUrl + " selected to forward eIDAS request");
+
+ if (basicConfig.getBasicConfiguration(
+ EidasConstants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD,
+ EidasConstants.FORWARD_METHOD_GET).equals(EidasConstants.FORWARD_METHOD_GET)) {
+
+ log.debug("Use http-redirect for eIDAS node forwarding ... ");
+ // send redirect
+ final UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(forwardUrl);
+ redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64);
+ httpResp.sendRedirect(redirectUrl.build().encode().toString());
+
+ } else {
+ log.debug("Use http-post for eIDAS node forwarding ... ");
+ final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
+ basicConfig,
+ pendingReq,
+ EidasConstants.TEMPLATE_POST_FORWARD_NAME,
+ null,
+ resourceLoader);
+
+ config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl);
+ config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_TOKEN_NAME,
+ EidasParameterKeys.TOKEN.toString());
+ config.putCustomParameter(null, EidasConstants.TEMPLATE_POST_FORWARD_TOKEN_VALUE,
+ tokenBase64);
+
+ guiBuilder.build(httpReq, httpResp, config, "Forward to eIDASNode form");
+
+ }
+ }
+
+ @PostConstruct
+ private void checkConfiguration() {
+ // TODO: validate configuration on start-up
+
+ }
+
+ private ImmutableAttributeMap buildAttributesFromAuthData(IAuthData authData,
+ ILightRequest eidasReq) {
+ final IEidAuthData eidAuthData = (IEidAuthData) authData;
+ final ImmutableAttributeMap.Builder attributeMap = ImmutableAttributeMap.builder();
+
+ // inject all requested attributres
+ injectRequestedAttributes(attributeMap, eidasReq, eidAuthData);
+
+ if (eidAuthData.isUseMandate()) {
+ log.debug("Building eIDAS Proxy-Service response with mandate ... ");
+ injectMdsRepesentativeInformation(attributeMap, eidAuthData, eidasReq.getRequestedAttributes());
+
+ // work-around that injects nat. person subject to bypass validation on eIDAS
+ // Node
+ injectJurPersonWorkaroundIfRequired(attributeMap, eidasReq, authData);
+
+ }
+
+ return attributeMap.build();
+
+ }
+
+ private void injectRequestedAttributes(ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq,
+ IEidAuthData eidAuthData) {
+ eidasReq.getRequestedAttributes().getAttributeMap().keySet().stream()
+ .forEach(el -> injectEidasAttribute(attributeMap, eidAuthData,
+ el.getNameUri().toString(), eidAuthData.isUseMandate()));
+
+ }
+
+ private void injectMdsRepesentativeInformation(
+ ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData,
+ ImmutableAttributeMap requestedAttributes) {
+ attrRegistry.getRepresentativeAttributesToAddByDefault()
+ .filter(el -> requestedAttributes.getAttributeValuesByNameUri(el) == null)
+ .forEach(el -> injectEidasAttribute(attributeMap, eidAuthData, el, true));
+
+ }
+
+ private void injectEidasAttribute(ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData,
+ String eidasAttrName, boolean mandatesUsed) {
+ final Optional<String> releatedIdaAttribute =
+ attrRegistry.mapEidasAttributeToSpecificIdaAttribute(eidasAttrName, mandatesUsed);
+ if (releatedIdaAttribute.isPresent()) {
+ log.trace("Mapping IDA attribute: {} to eIDAS attribute: {}", releatedIdaAttribute.get(),
+ eidasAttrName);
+ final String idaAttrValue = eidAuthData.getGenericData(releatedIdaAttribute.get(), String.class);
+ if (StringUtils.isNotEmpty(idaAttrValue)) {
+ log.debug("Build eIDAS attribute: {} from IDA attribute: {}", eidasAttrName, releatedIdaAttribute
+ .get());
+ attributeMap.put(
+ attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByName(eidasAttrName),
+ idaAttrValue);
+
+ } else {
+ log.info("No IDA attribute: {}, eIDAS attribute: {} will be ignored", releatedIdaAttribute.get(),
+ eidasAttrName);
+
+ }
+
+ } else {
+ Optional<String> advancedAttributeHandler = attrRegistry.mapEidasAttributeToAttributeHandler(eidasAttrName);
+ if (advancedAttributeHandler.isPresent()) {
+ final String idaAttrValue = context.getBean(advancedAttributeHandler.get(), IEidasAttributeHandler.class)
+ .buildAttributeValue(eidAuthData);
+ if (StringUtils.isNotEmpty(idaAttrValue)) {
+ log.debug("Build eIDAS attribute: {} by advanced attribute-handler: {}",
+ eidasAttrName, advancedAttributeHandler.get());
+ attributeMap.put(
+ attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByName(eidasAttrName),
+ idaAttrValue);
+
+ } else {
+ log.info("Empty attribte-value returned by advanced attribute-handler, eIDAS attribute: {} will be ignored",
+ eidasAttrName);
+
+ }
+
+ } else {
+ log.warn("Can not build eIDAS attribute: {}, because there is not corresponding IDA attribute defined",
+ eidasAttrName);
+
+ }
+ }
+ }
+
+ private BinaryLightToken putResponseInCommunicationCache(ILightResponse lightResponse)
+ throws ServletException {
+ final BinaryLightToken binaryLightToken;
+ try {
+ final SpecificCommunicationService springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+
+ binaryLightToken = springManagedSpecificConnectorCommunicationService.putResponse(lightResponse);
+
+ } catch (final SpecificCommunicationException e) {
+ log.error("Unable to process specific request");
+ throw new ServletException(e);
+
+ }
+
+ return binaryLightToken;
+ }
+
+ /**
+ * Work-around to inject representative information as nat. person subject to
+ * bypass eIDAS Node validation.
+ *
+ * <p>
+ * <b>Injection will only be done if this work-around is enabled by
+ * configuration, the mandator is a legal person, and both legal and natural
+ * person subject's is requested.</b>
+ * </p>
+ *
+ * @param attributeMap Attribute set for eIDAS response
+ * @param eidasReq Incoming eIDAS request
+ * @param authData Authentication data
+ */
+ private void injectJurPersonWorkaroundIfRequired(
+ ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, IAuthData authData) {
+
+ //TODO: maybe we have update that check, because we need an activation on Connector level
+ if (isLegalPersonWorkaroundActive() && isLegalPersonMandateAvailable(authData)
+ && EidasProxyServiceUtils.isNaturalPersonRequested(eidasReq)
+ && EidasProxyServiceUtils.isLegalPersonRequested(eidasReq)) {
+ log.debug(
+ "Injecting representative information as nat. person subject to bypass eIDAS Node validation");
+
+ final AttributeDefinition<?> attrDefPersonalId =
+ attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ final AttributeDefinition<?> attrDefFamilyName =
+ attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
+ final AttributeDefinition<?> attrDefGivenName =
+ attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first();
+ final AttributeDefinition<?> attrDefDateOfBirth =
+ attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first();
+
+ attributeMap.put(attrDefPersonalId, authData.getGenericData(PvpAttributeDefinitions.BPK_NAME,
+ String.class));
+ attributeMap.put(attrDefFamilyName, authData.getFamilyName());
+ attributeMap.put(attrDefGivenName, authData.getGivenName());
+ attributeMap.put(attrDefDateOfBirth, authData.getDateOfBirth());
+
+ }
+ }
+
+ private boolean isLegalPersonWorkaroundActive() {
+ return basicConfig.getBasicConfigurationBoolean(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_WORKAROUND_MANDATES_LEGAL_PERSON,
+ false);
+
+ }
+
+ private boolean isLegalPersonMandateAvailable(IAuthData authData) {
+ return StringUtils.isNoneEmpty(authData.getGenericData(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class));
+
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java
new file mode 100644
index 00000000..a3b5007a
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServicePendingRequest.java
@@ -0,0 +1,28 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.protocol;
+
+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 eu.eidas.auth.commons.light.ILightRequest;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * Pending-request of an authentication process from eIDAS Proxy-Service.
+ *
+ * @author tlenz
+ *
+ */
+@Component("ProxyServicePendingRequest")
+@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
+public class ProxyServicePendingRequest extends RequestImpl {
+
+ private static final long serialVersionUID = 4227378344716277935L;
+
+ @Getter
+ @Setter
+ ILightRequest eidasRequest;
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java
new file mode 100644
index 00000000..edb21722
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/service/ProxyEidasAttributeRegistry.java
@@ -0,0 +1,249 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.google.common.collect.Sets;
+
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.dto.attributes.AttrMappingElement;
+import at.asitplus.eidas.specific.modules.msproxyservice.handler.IEidasAttributeHandler;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class ProxyEidasAttributeRegistry {
+
+ private static final String ATTR_CONFIG_ALL = "*";
+
+ private static ObjectMapper mapper = new ObjectMapper();
+
+ @Autowired ApplicationContext context;
+ @Autowired IConfiguration basicConfig;
+ @Autowired ResourceLoader resourceLoader;
+
+
+ @Getter
+ private EidasAttributeRegistry coreRegistry;
+
+ private Set<AttrMappingElement> attributeConfiguration;
+
+
+ /**
+ * Attribute Registry for eIDAS Proxy-Service implementation.
+ * @param registry Core attribute registry
+ */
+ public ProxyEidasAttributeRegistry(@Autowired EidasAttributeRegistry registry) {
+ this.coreRegistry = registry;
+
+ }
+
+
+ /**
+ * Get all attributes that requested from IDA by default.
+ *
+ * @param withMandates <code>true</code> if mandates are supported, otherwise <code>false</code>
+ * @return {@link Stream} of IDA specific attribute names
+ */
+ @NonNull
+ public Stream<String> getAlwaysRequestedAttributes(boolean withMandates) {
+ return attributeConfiguration.stream()
+ .filter(el -> ATTR_CONFIG_ALL.equals(el.getEidasAttributeName()))
+ .map(el -> getReleadedIdaAttribute(el, withMandates))
+ .flatMap(Collection::stream)
+ .filter(Objects::nonNull);
+
+ }
+
+ /**
+ * Get all eIDAS attributes that are added by default in case of mandates.
+ *
+ * @return {@link Stream} of eIDAS attributes
+ */
+ @NonNull
+ public Stream<String> getRepresentativeAttributesToAddByDefault() {
+ return attributeConfiguration.stream()
+ .filter(el -> el.getType() != null && el.getType().getAutoIncludeWithMandates())
+ .map(el -> el.getEidasAttributeName());
+
+ }
+
+ /**
+ * Get IDA attributes for a specific eIDAS attribute.
+ *
+ * @param eidasAttributeName Name of the eIDAS attribute.
+ * @param withMandates <code>true</code> if mandates are supported, otherwise <code>false</code>
+ * @return {@link Set} of IDA specific attribute names
+ */
+ @NonNull
+ public Set<String> getIdaAttributesForEidasAttribute(String eidasAttributeName, boolean withMandates) {
+ return attributeConfiguration.stream()
+ .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName))
+ .findFirst()
+ .map(el -> getReleadedIdaAttribute(el, withMandates))
+ .orElse(Collections.emptySet())
+ .stream()
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+
+ }
+
+ /**
+ * Get eIDAS related IDA attribute for a specific mode-operation.
+ *
+ * @param eidasAttributeName Name of the eIDAS attribute.
+ * @param withMandates <code>true</code> if mandates are supported, otherwise <code>false</code>
+ * @return Name of the related IDA attribute if available
+ */
+ public Optional<String> mapEidasAttributeToSpecificIdaAttribute(
+ String eidasAttributeName, boolean withMandates) {
+ return attributeConfiguration.stream()
+ .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName))
+ .filter(el -> el.getIdaAttribute() != null)
+ .findFirst()
+ .map(el -> withMandates ? el.getIdaAttribute().getWithMandates() : el.getIdaAttribute().getBasic())
+ .filter(el -> StringUtils.isNotEmpty(el));
+
+ }
+
+ /**
+ * Get eIDAS related custom attribute-handler.
+ *
+ * @param eidasAttributeName Name of the eIDAS attribute.
+ * @return full classname of the handler implementation if available
+ */
+ public Optional<String> mapEidasAttributeToAttributeHandler(String eidasAttributeName) {
+ return attributeConfiguration.stream()
+ .filter(el -> el.getEidasAttributeName().equals(eidasAttributeName))
+ .filter(el -> StringUtils.isNotEmpty(el.getSpecificAttributeHandlerClass()))
+ .findFirst()
+ .map(el -> el.getSpecificAttributeHandlerClass());
+
+ }
+
+
+ @PostConstruct
+ private void initialize() throws EaafConfigurationException {
+ final String attrConfPath = basicConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION);
+
+ log.debug("Initializing eIDAS <--> IDA attribute mapping from: {} ... ", attrConfPath);
+
+ if (StringUtils.isEmpty(attrConfPath)) {
+ log.error("Error: Path to attribute-mapping config is unknown");
+ throw new EaafConfigurationException("internal.configuration.00",
+ new Object[]{MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION});
+
+ }
+
+ try {
+ // reading attribute-configuration file
+ final CollectionType javaType =
+ mapper.getTypeFactory().constructCollectionType(List.class, AttrMappingElement.class);
+ List<AttrMappingElement> internalAttributeConfiguration =
+ mapper.readValue(readFromFile(attrConfPath), javaType);
+ log.debug("Found #{} eIDAS <--> IDA attribute-mappings . Starting import process ... ",
+ internalAttributeConfiguration.size());
+
+ // post-validation of attribute configuration
+ attributeConfiguration = internalAttributeConfiguration.stream()
+ .filter(el -> checkEidasAttributeName(el))
+ .collect(Collectors.toSet());
+ log.info("Load {} eIDAS <--> IDA attribute-mappings into attribute-registry", attributeConfiguration.size());
+
+ } catch (Exception e) {
+ log.error("Error reading eIDAS <--> IDA attribute-mapping configuration file", e);
+ throw new EaafConfigurationException("internal.configuration.01",
+ new Object[]{MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_ATTIBUTE_CONFIGURATION,
+ "Error reading Configurations file"}, e);
+
+ }
+ }
+
+ private Set<String> getReleadedIdaAttribute(AttrMappingElement el, boolean withMandates) {
+ if (el.getIdaAttribute() != null) {
+ Set<String> directMapping = withMandates
+ ? Sets.newHashSet(el.getIdaAttribute().getBasic(), el.getIdaAttribute().getWithMandates())
+ : Sets.newHashSet(el.getIdaAttribute().getBasic());
+
+ if (el.getAddionalRequiredAttributes() != null) {
+ el.getAddionalRequiredAttributes().forEach(
+ attr -> directMapping.add(attr));
+
+ }
+ return directMapping;
+
+ } else {
+ return Collections.emptySet();
+
+ }
+ }
+
+ private boolean checkEidasAttributeName(AttrMappingElement el) {
+ if (StringUtils.isNotEmpty(el.getEidasAttributeName())) {
+ if (ATTR_CONFIG_ALL.equals(el.getEidasAttributeName())
+ || coreRegistry.getCoreAttributeRegistry().getByName(el.getEidasAttributeName()) != null) {
+
+ // check if custom attribute-handler implementation is available
+ if (StringUtils.isNotEmpty(el.getSpecificAttributeHandlerClass())) {
+ try {
+ context.getBean(el.getSpecificAttributeHandlerClass(), IEidasAttributeHandler.class);
+
+ } catch (Exception e) {
+ log.error("No custom attribute-handler implementation for: {}", el.getSpecificAttributeHandlerClass(), e);
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ log.warn("eIDAS attribute: {} is UNKNOWN by eIDAS node. Ignore it!", el.getEidasAttributeName());
+
+ }
+
+ } else {
+ log.warn("Find attribute-mapping element WITHOUT eIDAS attribute-name. Ignore it!");
+
+ }
+
+ return false;
+ }
+
+ private byte[] readFromFile(final String filePath) throws URISyntaxException, IOException {
+ final String fullFilePath = FileUtils.makeAbsoluteUrl(filePath, basicConfig.getConfigurationRootDirectory());
+ final Resource ressource = resourceLoader.getResource(fullFilePath);
+ final InputStream is = ressource.getInputStream();
+ final byte[] result = IOUtils.toByteArray(is);
+ is.close();
+ return result;
+
+ }
+
+
+}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java
new file mode 100644
index 00000000..b8a4c598
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/utils/EidasProxyServiceUtils.java
@@ -0,0 +1,45 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.utils;
+
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import eu.eidas.auth.commons.light.ILightRequest;
+
+/**
+ * Common utils for eIDAS Proxy-Service implementation.
+ *
+ * @author tlenz
+ *
+ */
+public class EidasProxyServiceUtils {
+
+ /**
+ * Check if legal person subject is requested by eIDAS Connector.
+ *
+ * @param eidasRequest Authentication request from eIDAS Connector.
+ * @return <code>true</code> if <i>LegalPersonIdentifier</i> is requested, otherwise <code>false</code>lse
+ */
+ public static boolean isLegalPersonRequested(ILightRequest eidasRequest) {
+ return eidasRequest.getRequestedAttributes().entrySet().stream()
+ .filter(el -> el.getKey().getFriendlyName().equals(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER))
+ .findFirst()
+ .isPresent();
+
+ }
+
+ /**
+ * Check if natural person subject is requested by eIDAS Connector.
+ *
+ * @param eidasRequest Authentication request from eIDAS Connector.
+ * @return <code>true</code> if <i>PersonIdentifier</i> is requested, otherwise <code>false</code>lse
+ */
+ public static boolean isNaturalPersonRequested(ILightRequest eidasRequest) {
+ return eidasRequest.getRequestedAttributes().entrySet().stream()
+ .filter(el -> el.getKey().getFriendlyName().equals(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER))
+ .findFirst()
+ .isPresent();
+
+ }
+
+ private EidasProxyServiceUtils() {
+ //hide constructor for class with static methods only
+ }
+}
diff --git a/modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
new file mode 100644
index 00000000..9158d2e6
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
@@ -0,0 +1 @@
+at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceSpringResourceProvider \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties b/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
new file mode 100644
index 00000000..3f92d58a
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
@@ -0,0 +1,14 @@
+eidas.proxyservice.01=General error on request-validation from national eIDAS Proxy-Service
+eidas.proxyservice.02=Authentication request contains not communication token.
+eidas.proxyservice.03=General error during eIDAS-Node communication. Reason: {}
+eidas.proxyservice.04=Validation of eIDAS Authn request failed. Reason: {}
+eidas.proxyservice.05=No eIDAS-Connector Issuer in Authn. request. Authentication not possible
+eidas.proxyservice.06=Can not build eIDAS Proxy-Service response. Authentication FAILED.
+eidas.proxyservice.07=Can not determine eIDAS-Connector CountryCode. Authentication not possible
+eidas.proxyservice.08=Validation of eIDAS Authn request failed. Reason: Legal person and natural person can not be requested at once.
+eidas.proxyservice.09=eIDAS authentication not possible, because legal person is requested but mandates are disabled in general
+eidas.proxyservice.10=eIDAS authentication not possible, because legal person is requested but not mandate profiles are defined
+eidas.proxyservice.11=No Authentication request with stated communication token.
+
+
+eidas.proxyservice.99=Internal error during eIDAS Proxy-Service authentication \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml
new file mode 100644
index 00000000..38bd44da
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/main/resources/spring/eidas_proxy-service.beans.xml
@@ -0,0 +1,41 @@
+<?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">
+
+ <context:annotation-config />
+
+ <bean id="ProxyServicePendingRequest"
+ class="at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest"
+ scope="prototype"/>
+
+ <bean id="ProxyServiceAuthenticationAction"
+ class="at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction"/>
+
+ <bean id="msSpecificProxyController"
+ class="at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController"/>
+
+ <bean id="eidasProxyMessageSource"
+ class="at.asitplus.eidas.specific.modules.msproxyservice.EidasProxyMessageSource"/>
+
+ <bean id="attributeRegistry"
+ class="at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry">
+ <property name="eidasAttributesFile"
+ ref="specificConnectorAttributesFileWithPath" />
+ <property name="additionalAttributesFile"
+ ref="specificConnectorAdditionalAttributesFileWithPath" />
+ </bean>
+
+ <bean id="proxyAttributeRegistry"
+ class="at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry" />
+
+ <bean id="at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler"
+ class="at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler" />
+
+</beans> \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java
new file mode 100644
index 00000000..fc4ad2b6
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/EidasProxyMessageSourceTest.java
@@ -0,0 +1,50 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.test;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.modules.msproxyservice.EidasProxyMessageSource;
+import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ })
+public class EidasProxyMessageSourceTest {
+
+ @Autowired
+ private ResourceLoader loader;
+ @Autowired(required = false)
+ private List<IMessageSourceLocation> messageSources;
+
+ @Test
+ public void checkMessageSources() {
+ Assert.assertNotNull("No messageSource", messageSources);
+ Assert.assertFalse("No message source", messageSources.isEmpty());
+
+ boolean found = false;
+
+ for (final IMessageSourceLocation messageSource : messageSources) {
+ found = found ? found : messageSource instanceof EidasProxyMessageSource;
+
+ Assert.assertNotNull("No sourcePath", messageSource.getMessageSourceLocation());
+ for (final String el : messageSource.getMessageSourceLocation()) {
+ final Resource messages = loader.getResource(el + ".properties");
+ Assert.assertTrue("Source not exist", messages.exists());
+
+ }
+ }
+
+ Assert.assertTrue("Internal messagesource not found", found);
+
+ }
+}
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java
new file mode 100644
index 00000000..9a690664
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/MsProxyServiceSpringResourceProviderTest.java
@@ -0,0 +1,56 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.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.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceSpringResourceProvider;
+import at.gv.egiz.eaaf.core.test.TestConstants;
+
+
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class MsProxyServiceSpringResourceProviderTest {
+
+ @Test
+ public void testSpringConfig() {
+ final MsProxyServiceSpringResourceProvider test =
+ new MsProxyServiceSpringResourceProvider();
+ 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",
+ MsProxyServiceSpringResourceProvider.class.getName(), spiFile);
+
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found");
+
+ }
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java
new file mode 100644
index 00000000..dfa4e264
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java
@@ -0,0 +1,197 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.test.protocol;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService;
+import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyProtocolAuthService;
+import eu.eidas.auth.commons.EidasParameterKeys;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig2.xml",
+ })
+@EnableWebMvc
+public class EidasProxyServiceControllerBorisTest {
+
+ @Autowired private EidasProxyServiceController controller;
+
+ @Autowired private DummySpecificCommunicationService proxyService;
+ @Autowired private DummyProtocolAuthService authService;
+ @Autowired private EidasAttributeRegistry attrRegistry;
+ @Autowired private ApplicationContext context;
+
+ @Autowired MsConnectorDummyConfigMap config;
+
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+
+ private SpecificCommunicationService springManagedSpecificConnectorCommunicationService;
+
+ /**
+ * jUnit test set-up.
+ */
+ @Before
+ public void setUp() throws EaafStorageException, URISyntaxException {
+ httpReq = new MockHttpServletRequest("POST", "http://localhost/ms_connector/eidas/light/idp/redirect");
+ httpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ proxyService.setiLightRequest(null);
+ proxyService.setError(null);
+
+ config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint",
+ "http://eidas.proxy/endpoint");
+
+ springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithBorisAttributeLegal() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ "eJusticeLegalPersonRole").first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size());
+ assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0));
+ assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 10, spConfig.getRequestedAttributes().size());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithBorisAttributeNat() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ "eJusticeNaturalPersonRole").first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size());
+ assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0));
+ assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 6, spConfig.getRequestedAttributes().size());
+
+ }
+
+}
+
+
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java
new file mode 100644
index 00000000..5894ea45
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerTest.java
@@ -0,0 +1,852 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.test.protocol;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.core.StatusCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService;
+import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyProtocolAuthService;
+import eu.eidas.auth.commons.EidasParameterKeys;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.ILightResponse;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ })
+@EnableWebMvc
+public class EidasProxyServiceControllerTest {
+
+ @Autowired private EidasProxyServiceController controller;
+
+ @Autowired private DummySpecificCommunicationService proxyService;
+ @Autowired private DummyProtocolAuthService authService;
+ @Autowired private EidasAttributeRegistry attrRegistry;
+ @Autowired private ApplicationContext context;
+
+ @Autowired MsConnectorDummyConfigMap config;
+
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+
+ private SpecificCommunicationService springManagedSpecificConnectorCommunicationService;
+
+ /**
+ * jUnit test set-up.
+ */
+ @Before
+ public void setUp() throws EaafStorageException, URISyntaxException {
+ httpReq = new MockHttpServletRequest("POST", "http://localhost/ms_connector/eidas/light/idp/redirect");
+ httpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ proxyService.setiLightRequest(null);
+ proxyService.setError(null);
+
+ config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint",
+ "http://eidas.proxy/endpoint");
+
+ springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+
+ }
+
+ @Test
+ public void generateErrorResponseWrongPendingReq() throws Throwable {
+ Assert.assertFalse("wrong statusCode", controller.generateErrorMessage(
+ new EaafException("1000"),
+ httpReq, httpResp, null));
+
+ }
+
+ @Test
+ public void generateErrorResponse() throws Throwable {
+ ProxyServicePendingRequest pendingReq = new ProxyServicePendingRequest();
+ pendingReq.initialize(httpReq, config);
+
+ LightRequest.Builder eidasRequestBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requesterId(RandomStringUtils.randomAlphanumeric(10))
+ .providerName(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ // execute test
+ Assert.assertTrue("wrong statusCode", controller.generateErrorMessage(
+ new EaafException("1000"),
+ httpReq, httpResp,
+ pendingReq));
+
+ // validate state
+ assertNotNull("not redirct Header", httpResp.getHeader("Location"));
+ assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token="));
+ String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length());
+
+ ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token, "UTF-8"),
+ ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes()));
+
+ assertNotNull("responseId", resp.getId());
+ assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId());
+ assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState());
+
+ assertNotNull("subjectNameId", resp.getSubject());
+ assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat());
+ assertTrue("not attributes", resp.getAttributes().isEmpty());
+
+ assertEquals("StatusCode", StatusCode.RESPONDER, resp.getStatus().getStatusCode());
+ //assertEquals("SubStatusCode", "", resp.getStatus().getSubStatusCode());
+ //assertEquals("StatusMsg", "", resp.getStatus().getStatusMessage());
+
+ }
+
+ @Test
+ public void missingEidasToken() {
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.02", exception.getErrorId());
+
+ }
+
+ @Test
+ public void wrongEidasTokenWithNullpointerException() {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.11", exception.getErrorId());
+
+ }
+
+ @Test
+ public void wrongEidasTokenCacheCommunicationError() {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ proxyService.setError(new SpecificCommunicationException(RandomStringUtils.randomAlphanumeric(10)));
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.03", exception.getErrorId());
+ Assert.assertTrue("Wrong exception", (exception.getCause() instanceof SpecificCommunicationException));
+
+ }
+
+ @Test
+ public void missingServiceProviderCountry() {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH);
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.07", exception.getErrorId());
+
+ }
+
+ @Test
+ public void requestingLegalAndNaturalPerson() {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.08", exception.getErrorId());
+
+ }
+
+ @Test
+ public void requestLegalPersonButNoMandates() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.09", exception.getErrorId());
+
+ }
+
+ @Test
+ public void validAuthnRequest() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_BIRTHNAME).first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ Assert.assertNotNull("pendingRequest", authService.getPendingReq());
+ Assert.assertTrue("wrong pendingRequest", authService.getPendingReq() instanceof ProxyServicePendingRequest);
+ ProxyServicePendingRequest pendingReq = (ProxyServicePendingRequest) authService.getPendingReq();
+ Assert.assertNotNull("missing uniqueSpId", pendingReq.getSpEntityId());
+ Assert.assertNotNull("missing eidasReq", pendingReq.getEidasRequest());
+
+ Assert.assertFalse("isPassive", pendingReq.isPassiv());
+ Assert.assertTrue("isPassive", pendingReq.forceAuth());
+ Assert.assertFalse("isPassive", pendingReq.isAuthenticated());
+ Assert.assertFalse("isPassive", pendingReq.isAbortedByUser());
+ Assert.assertTrue("isPassive", pendingReq.isNeedAuthentication());
+
+ Assert.assertNotNull("missing spConfig", pendingReq.getServiceProviderConfiguration());
+ ServiceProviderConfiguration spConfig =
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ Assert.assertNotNull("uniqueId", spConfig.getUniqueIdentifier());
+ Assert.assertEquals("uniqueId wrong pattern",
+ authnReqBuilder.build().getIssuer(),
+ spConfig.getUniqueIdentifier());
+ Assert.assertEquals("friendlyName wrong pattern",
+ MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, spCountryCode, "public"),
+ spConfig.getFriendlyName());
+
+ Assert.assertEquals("uniqueId not match to pendingReq",
+ pendingReq.getSpEntityId(), spConfig.getUniqueIdentifier());
+ Assert.assertNotNull("bpkTarget", spConfig.getAreaSpecificTargetIdentifier());
+ Assert.assertEquals("wrong bPK Target",
+ EaafConstants.URN_PREFIX_EIDAS + "AT+" + spCountryCode,
+ spConfig.getAreaSpecificTargetIdentifier());
+
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 4, spConfig.getRequestedAttributes().size());
+
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesDefaultProfilesNat() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfilesNat.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesNat.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 6, spConfig.getRequestedAttributes().size());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesDefaultProfilesJur() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfilesJur.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesJur.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 9, spConfig.getRequestedAttributes().size());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesDefaultNoJurProfiles() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, "");
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.10", exception.getErrorId());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesDefaultNoNatProfiles() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL, "");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, "");
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 3, spConfig.getRequestedAttributes().size());
+
+ }
+
+ @Test
+ public void validAuthnRequestIssueSpecificNoMandates() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ // set specific mandate configuration
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "false");
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ StringUtils.join(mandateProfiles, ","));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode());
+
+ }
+
+ @Test
+ public void validAuthnRequestIssueSpecificMandatesNat() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+
+ String issuer = "https://apps.egiz.gv.at/EidasNode//ConnectorMetadata";
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ // set specific mandate configuration
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true");
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ StringUtils.join(mandateProfiles, ","));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode());
+
+ }
+
+ @Test
+ public void validAuthnRequestIssueSpecificMandatesJur() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ // set specific mandate configuration
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true");
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(mandateProfiles, ","));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesProfilesBoth() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+
+ // add custom SP config to allow both MDS in single request
+ addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true");
+
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+ addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ addConnectorConfig(25, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, "false");
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfilesNat.size() + mandateProfilesJur.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el,
+ mandateProfilesNat.contains(el) || mandateProfilesJur.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.BOTH, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 10, spConfig.getRequestedAttributes().size());
+
+ }
+
+
+ @Test
+ public void validAuthnRequestWithBorisAttributeLegal() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ "eJusticeLegalPersonRole").first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size());
+ assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0));
+ assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 11, spConfig.getRequestedAttributes().size());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithBorisAttributeNat() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ "eJusticeNaturalPersonRole").first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", 1, spConfig.getMandateProfiles().size());
+ assertEquals("mandateprofile", "MUST_BE_UPDATED", spConfig.getMandateProfiles().get(0));
+ assertEquals("MandateMode", SpMandateModes.LEGAL, spConfig.getMandateMode());
+
+ assertEquals("requested IDA attributes", 7, spConfig.getRequestedAttributes().size());
+ assertTrue("missing additional attribute", spConfig.getRequestedAttributes().stream()
+ .filter(el -> el.equals("testAttribute"))
+ .findFirst()
+ .isPresent());
+
+ }
+
+
+ private void addConnectorConfig(int i, String key, String value) {
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key,
+ value);
+
+ }
+
+}
+
+
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java
new file mode 100644
index 00000000..d9bc017c
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java
@@ -0,0 +1,982 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.test.protocol;
+
+import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.joda.time.DateTime;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap;
+import at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummySpConfiguration;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.ILightResponse;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ })
+public class ProxyServiceAuthenticationActionTest {
+
+ @Autowired private MsConnectorDummyConfigMap basicConfig;
+ @Autowired private ProxyServiceAuthenticationAction action;
+ @Autowired private ApplicationContext context;
+ @Autowired EidasAttributeRegistry attrRegistry;
+
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+ private ProxyServicePendingRequest pendingReq;
+ private MsConnectorDummySpConfiguration oaParam;
+ private SpecificCommunicationService springManagedSpecificConnectorCommunicationService;
+
+
+ /**
+ * jUnit test set-up.
+ * @throws EaafException In case of an error
+ */
+ @Before
+ public void setUp() throws URISyntaxException, EaafException {
+ httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler");
+ httpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint",
+ "http://eidas.proxy/endpoint");
+ basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson",
+ "false");
+
+ final Map<String, String> spConfig = new HashMap<>();
+ spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp");
+ spConfig.put("target", "urn:publicid:gv.at:cdid+XX");
+ spConfig.put(PROP_CONFIG_SP_NEW_EID_MODE, "true");
+ oaParam = new MsConnectorDummySpConfiguration(spConfig, basicConfig);
+ oaParam.setLoa(Arrays.asList(EaafConstants.EIDAS_LOA_HIGH));
+
+ pendingReq = new ProxyServicePendingRequest();
+ pendingReq.initialize(httpReq, basicConfig);
+ pendingReq.setOnlineApplicationConfiguration(oaParam);
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+
+ }
+
+ @Test
+ public void wrongPendingRequestType() {
+ IAuthData authData = generateDummyAuthData();
+ TestRequestImpl internalPendingReq = new TestRequestImpl();
+
+ EaafException exception = assertThrows(EaafException.class,
+ () -> action.processRequest(internalPendingReq, httpReq, httpResp, authData));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.99", exception.getErrorId());
+
+ }
+
+ @Test
+ public void missingForwardUrl() {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false);
+ basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint");
+
+ EaafException exception = assertThrows(EaafException.class,
+ () -> action.processRequest(pendingReq, httpReq, httpResp, authData));
+ Assert.assertEquals("wrong errorCode", "config.08", exception.getErrorId());
+
+ }
+
+ @Test
+ public void responseWithoutMandate() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME, RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 4, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
+ authData.getDateOfBirth());
+
+ }
+
+ @Test
+ public void responseWithoutMandateAndOptionalAttributesExist() throws EaafException, SpecificCommunicationException {
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByName("http://eidas.europa.eu/attributes/naturalperson/BirthName"))
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ attr.put("ida_birthname", RandomStringUtils.randomAlphanumeric(10));
+
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 5, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
+ authData.getDateOfBirth());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_BIRTHNAME,
+ (String) attr.get("ida_birthname"));
+
+ }
+
+ @Test
+ public void responseWithoutMandateAndOptionalAttributesNotExist() throws EaafException, SpecificCommunicationException {
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByName("http://eidas.europa.eu/attributes/naturalperson/BirthName"))
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 4, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
+ authData.getDateOfBirth());
+
+ }
+
+
+ @Test
+ public void responseWithNatMandate() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ "1985-11-15");
+
+
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 8, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth());
+
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME));
+
+ }
+
+ @Test
+ public void responseWithNatMandateOptionalAttribute() throws EaafException, SpecificCommunicationException {
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByName("http://eidas.europa.eu/attributes/naturalperson/BirthName"))
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ attr.put("ida_birthName_mandator", RandomStringUtils.randomAlphanumeric(10));
+ attr.put("ida_birthName", RandomStringUtils.randomAlphanumeric(10));
+
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ "1985-11-15");
+
+
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 9, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth());
+
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME));
+
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_BIRTHNAME,
+ (String) attr.get("ida_birthName_mandator"));
+
+ }
+
+ @Test
+ public void responseWithJurMandate() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 6, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth());
+
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME));
+
+ assertNull("find nat. person subject: personalId",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER));
+ assertNull("find nat. person subject: familyName",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME));
+ assertNull("find nat. person subject: givenName",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME));
+ assertNull("find nat. person subject: dateOfBirth",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH));
+
+ }
+
+ @Test
+ public void borisModeResponseWithJurMandate() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME,
+ "MUST_BE_UPDATED");
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 8, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth());
+
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME));
+
+ checkAttrValue(respAttr, "eJusticeLegalPersonRole", "VIP1");
+ checkAttrValue(respAttr, "eJusticeNaturalPersonRole", "VIP1");
+
+ assertNull("find nat. person subject: personalId",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER));
+ assertNull("find nat. person subject: familyName",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME));
+ assertNull("find nat. person subject: givenName",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME));
+ assertNull("find nat. person subject: dateOfBirth",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH));
+
+ }
+
+ @Test
+ public void borisModeResponseWithJurMandate2() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME,
+ "SECOND");
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 8, respAttr.size());
+
+ checkAttrValue(respAttr, "eJusticeLegalPersonRole", "VIP2");
+ checkAttrValue(respAttr, "eJusticeNaturalPersonRole", "VIP2");
+
+
+ }
+
+ @Test
+ public void borisModeNoMandateType() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 6, respAttr.size());
+
+ }
+
+ @Test
+ public void borisModeEmptyMandateType() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME, "");
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 6, respAttr.size());
+
+ }
+
+ @Test
+ public void borisModeUnknownMandateType() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_TYPE_NAME, RandomStringUtils.randomAlphanumeric(10));
+
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeLegalPersonRole").first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName("eJusticeNaturalPersonRole").first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 6, respAttr.size());
+
+ }
+
+ @Test
+ public void responseWithNatMandateWithWorkAround() throws EaafException, SpecificCommunicationException {
+ basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson",
+ "true");
+
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ "1985-11-15");
+
+
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 8, respAttr.size());
+
+ }
+
+ @Test
+ public void responseWithJurMandateWithWorkAround() throws EaafException, SpecificCommunicationException {
+ basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson",
+ "true");
+
+ //request natural person subject only
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 10, respAttr.size());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(PvpAttributeDefinitions.BPK_NAME));
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, authData.getDateOfBirth());
+
+ }
+
+ @Test
+ public void responseWithJurMandateWithWorkAroundNoNatSubject() throws EaafException, SpecificCommunicationException {
+ basicConfig.putConfigValue("auth.eIDAS.proxy.workaround.mandates.legalperson",
+ "true");
+
+ //request natural person subject only
+ LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest();
+ eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .build());
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(PvpAttributeDefinitions.BPK_NAME,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 6, respAttr.size());
+ assertNull("find nat. person subject: personalId",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER));
+ assertNull("find nat. person subject: familyName",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME));
+ assertNull("find nat. person subject: givenName",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME));
+ assertNull("find nat. person subject: dateOfBirth",
+ getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH));
+
+ }
+
+ @Test
+ public void checkBasicConstrainsInAction() {
+
+ Assert.assertTrue("Wrong NeedAuthentication", action.needAuthentication(pendingReq, httpReq, httpResp));
+ Assert.assertNotNull("Missing ActionName", action.getDefaultActionName());
+
+ Assert.assertNotNull("missing ActionBean", context.getBean(ProxyServiceAuthenticationAction.class));
+
+ }
+
+ private IAuthData generateDummyAuthData() {
+ return generateDummyAuthData(new HashMap<>(), EaafConstants.EIDAS_LOA_LOW,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01", false);
+
+ }
+
+ private Object getAttrValue(ImmutableAttributeMap respAttr, String attrName) {
+ final AttributeDefinition<?> attrDef =
+ attrRegistry.getCoreAttributeRegistry().getByFriendlyName(attrName).first();
+ return respAttr.getFirstValue(attrDef);
+
+ }
+
+ private void checkAttrValue(ImmutableAttributeMap respAttr, String attrName, String expected) {
+ Object value = getAttrValue(respAttr, attrName);
+ assertNotNull("not attr value: " + attrName, value);
+
+ if (value instanceof String) {
+ assertEquals("wrong attr. value: " + attrName, expected, value);
+
+ } else if ( value instanceof DateTime) {
+ assertEquals("wrong attr. value: " + attrName, expected, ((DateTime)value).toString("yyyy-MM-dd"));
+
+ }
+ }
+
+ private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData) throws SpecificCommunicationException {
+ assertNotNull("not redirct Header", httpResp.getHeader("Location"));
+ assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token="));
+ String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length());
+
+ ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token),
+ ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes()));
+
+ assertNotNull("responseId", resp.getId());
+ assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId());
+ assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState());
+ assertEquals("LoA", authData.getEidasQaaLevel(), resp.getLevelOfAssurance());
+
+ assertNotNull("subjectNameId", resp.getSubject());
+ assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat());
+
+ assertFalse("not attributes", resp.getAttributes().isEmpty());
+ return resp.getAttributes();
+
+ }
+
+ private Builder generateBasicLightRequest() {
+ return LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requesterId(RandomStringUtils.randomAlphanumeric(10))
+ .providerName(RandomStringUtils.randomAlphanumeric(10))
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first())
+ .build()
+ );
+ }
+
+ private IAuthData generateDummyAuthData(Map<String, Object> attrs, String loa, String familyName, String givenName, String dateOfBirth,
+ boolean useMandates) {
+ attrs.put(PvpAttributeDefinitions.BIRTHDATE_NAME, dateOfBirth);
+ attrs.put(PvpAttributeDefinitions.GIVEN_NAME_NAME, givenName);
+ attrs.put(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, familyName);
+
+ return new IEidAuthData() {
+
+ @Override
+ public boolean isSsoSession() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isForeigner() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isBaseIdTransferRestrication() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public Instant getSsoSessionValidTo() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getSessionIndex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getNameIdFormat() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getNameID() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public IIdentityLink getIdentityLink() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getIdentificationValue() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getIdentificationType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getGivenName() {
+ return givenName;
+ }
+
+ @Override
+ public <T> T getGenericData(String key, Class<T> clazz) {
+ if (attrs.containsKey(key)) {
+ return (T) attrs.get(key);
+
+ } else {
+ return null;
+ }
+
+ }
+
+ @Override
+ public String getDateOfBirth() {
+ return dateOfBirth;
+ }
+
+ @Override
+ public String getFamilyName() {
+ return familyName;
+ }
+
+ @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 loa;
+
+ }
+
+
+ @Override
+ public String getCiticenCountryCode() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getBpkType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getBpk() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getAuthenticationIssuer() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getAuthenticationIssueInstantString() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Instant getAuthenticationIssueInstant() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public byte[] getSignerCertificate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public byte[] getEidToken() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public EidIdentityStatusLevelValues getEidStatus() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getVdaEndPointUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean isUseMandate() {
+ return useMandates;
+
+ }
+
+ @Override
+ public String getDateOfBirthFormated(String pattern) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+
+ }
+}
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java
new file mode 100644
index 00000000..b6b8a8df
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/services/ProxyEidasAttributeRegistryTest.java
@@ -0,0 +1,162 @@
+package at.asitplus.eidas.specific.modules.msproxyservice.test.services;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import at.asitplus.eidas.specific.modules.msproxyservice.service.ProxyEidasAttributeRegistry;
+import lombok.NonNull;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/spring/SpringTest-context_basic_test.xml",
+ "/spring/SpringTest-context_basic_mapConfig.xml",
+ })
+@EnableWebMvc
+public class ProxyEidasAttributeRegistryTest {
+
+ @Autowired ProxyEidasAttributeRegistry attrRegistry;
+
+ @Test
+ public void checkDefaultAttributes() {
+ assertEquals("default attributes without mandates", 2,
+ attrRegistry.getAlwaysRequestedAttributes(false).count());
+ assertEquals("default attributes with mandates", 4,
+ attrRegistry.getAlwaysRequestedAttributes(true).count());
+
+ }
+
+ @Test
+ public void eidasAttributeMapping() {
+ checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", false,
+ Arrays.asList("urn:oid:1.2.40.0.10.2.1.1.149"));
+ checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", true,
+ Arrays.asList("urn:oid:1.2.40.0.10.2.1.1.149", "urn:oid:1.2.40.0.10.2.1.1.261.98"));
+
+ }
+
+ @Test
+ public void eidasAttributeMappingMandateOnly() {
+ checkAttributeMapping("http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", false,
+ Arrays.asList(
+ "urn:oid:1.2.40.0.10.2.1.1.149",
+ "urn:oid:2.5.4.42",
+ "urn:oid:1.2.40.0.10.2.1.1.261.20",
+ "urn:oid:1.2.40.0.10.2.1.1.55"));
+ checkAttributeMapping("http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier", true,
+ Arrays.asList(
+ "urn:oid:1.2.40.0.10.2.1.1.261.100",
+ "urn:oid:1.2.40.0.10.2.1.1.149",
+ "urn:oid:2.5.4.42",
+ "urn:oid:1.2.40.0.10.2.1.1.261.20",
+ "urn:oid:1.2.40.0.10.2.1.1.55"));
+
+ }
+
+ @Test
+ public void eidasAttributeMappingWithNoIdaAttribute() {
+ checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", false,
+ Collections.emptyList());
+ checkAttributeMapping("http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", true,
+ Collections.emptyList());
+
+ }
+
+ @Test
+ public void unknownEidasAttribute() {
+ checkAttributeMapping("http://eidas.europa.eu/attributes/jUnit/not/exits", false,
+ Collections.emptyList());
+ checkAttributeMapping("http://eidas.europa.eu/attributes/jUnit/not/exits", true,
+ Collections.emptyList());
+
+ }
+
+ @Test
+ public void unknownEidasAttribute2() {
+ checkAttributeMapping(RandomStringUtils.randomAlphabetic(10), false,
+ Collections.emptyList());
+ checkAttributeMapping(RandomStringUtils.randomAlphabetic(10), true,
+ Collections.emptyList());
+
+ }
+
+ @Test
+ public void attributeResponseMapping() {
+ assertFalse("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute(
+ "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", false).isPresent());
+ assertFalse("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute(
+ "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", true).isPresent());
+
+
+ Optional<String> attr1 = attrRegistry.mapEidasAttributeToSpecificIdaAttribute(
+ "http://eidas.europa.eu/attributes/naturalperson/BirthName", false);
+ assertTrue("find wrong IDA mapping", attr1.isPresent());
+ assertEquals("find wrong IDA mapping value", "ida_birthname", attr1.get());
+
+ Optional<String> attr2 = attrRegistry.mapEidasAttributeToSpecificIdaAttribute(
+ "http://eidas.europa.eu/attributes/naturalperson/BirthName", true);
+ assertTrue("find wrong IDA mapping", attr2.isPresent());
+ assertEquals("find wrong IDA mapping value", "ida_birthName_mandator", attr2.get());
+
+
+ assertTrue("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute(
+ "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", false).isPresent());
+ assertTrue("find wrong IDA mapping", attrRegistry.mapEidasAttributeToSpecificIdaAttribute(
+ "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", true).isPresent());
+
+ }
+
+ @Test
+ public void defaultRepresentativeAttributes() {
+ assertEquals("wrong number of rep. attributes", 4,
+ attrRegistry.getRepresentativeAttributesToAddByDefault().count());
+
+ }
+
+ @Test
+ public void specificAttributeHandler() {
+ assertFalse("find wrong attribute",
+ attrRegistry.mapEidasAttributeToAttributeHandler(
+ "http://eidas.europa.eu/attributes/jUnit/no/custom/handler").isPresent());
+
+ assertFalse("find wrong attribute",
+ attrRegistry.mapEidasAttributeToAttributeHandler(
+ "http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth").isPresent());
+
+ assertFalse("find wrong attribute",
+ attrRegistry.mapEidasAttributeToAttributeHandler(
+ "http://e-justice.europa.eu/attributes/legalperson/eJusticePersonRoleNotExist").isPresent());
+
+ Optional<String> attr2 = attrRegistry.mapEidasAttributeToAttributeHandler(
+ "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole");
+ assertTrue("find wrong IDA mapping", attr2.isPresent());
+ assertEquals("find wrong specific attribute-handler",
+ "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler", attr2.get());
+
+ }
+
+
+ private void checkAttributeMapping(String eidasAttr, boolean withMandates, List<String> idaAttributes) {
+ @NonNull
+ Set<String> idaAttrResult = attrRegistry.getIdaAttributesForEidasAttribute(eidasAttr, withMandates);
+ assertEquals("wrong number of IDA attributes", idaAttributes.size(), idaAttrResult.size());
+ idaAttributes.forEach(
+ el -> assertTrue("missing: " + el, idaAttrResult.contains(el)));
+
+ }
+
+}
diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml
new file mode 100644
index 00000000..c7b40d90
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/config/additional-attributes.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# Copyright (c) 2017 European Commission
+# 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/page/eupl-text-11-12
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the Licence for the specific language governing permissions and limitations under the Licence.
+ -->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <comment>Dynamic attributes</comment>
+
+ <entry key="1.NameUri">http://eidas.europa.eu/attributes/naturalperson/AdditionalAttribute</entry>
+ <entry key="1.FriendlyName">AdditionalAttribute</entry>
+ <entry key="1.PersonType">NaturalPerson</entry>
+ <entry key="1.Required">false</entry>
+ <entry key="1.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="1.XmlType.LocalPart">string</entry>
+ <entry key="1.XmlType.NamespacePrefix">xs</entry>
+ <entry key="1.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="2.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalAdditionalAttribute</entry>
+ <entry key="2.FriendlyName">LegalAdditionalAttribute</entry>
+ <entry key="2.PersonType">LegalPerson</entry>
+ <entry key="2.Required">false</entry>
+ <entry key="2.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="2.XmlType.LocalPart">string</entry>
+ <entry key="2.XmlType.NamespacePrefix">xs</entry>
+ <entry key="2.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="3.NameUri">http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole</entry>
+ <entry key="3.FriendlyName">eJusticeNaturalPersonRole</entry>
+ <entry key="3.PersonType">NaturalPerson</entry>
+ <entry key="3.Required">false</entry>
+ <entry key="3.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="3.XmlType.LocalPart">string</entry>
+ <entry key="3.XmlType.NamespacePrefix">xs</entry>
+ <entry key="3.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="4.NameUri">http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole</entry>
+ <entry key="4.FriendlyName">eJusticeLegalPersonRole</entry>
+ <entry key="4.PersonType">LegalPerson</entry>
+ <entry key="4.Required">false</entry>
+ <entry key="4.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="4.XmlType.LocalPart">string</entry>
+ <entry key="4.XmlType.NamespacePrefix">xs</entry>
+ <entry key="4.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="5.NameUri">http://e-justice.europa.eu/attributes/legalperson/eJusticePersonRoleNotExist</entry>
+ <entry key="5.FriendlyName">eJusticeLegalPersonRole</entry>
+ <entry key="5.PersonType">LegalPerson</entry>
+ <entry key="5.Required">false</entry>
+ <entry key="5.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="5.XmlType.LocalPart">string</entry>
+ <entry key="5.XmlType.NamespacePrefix">xs</entry>
+ <entry key="5.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+
+
+</properties>
diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml b/modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml
new file mode 100644
index 00000000..cbae35db
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/config/eidas-attributes.xml
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# Copyright (c) 2017 European Commission
+# 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/page/eupl-text-11-12
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the Licence for the specific language governing permissions and limitations under the Licence.
+ -->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <comment>eIDAS attributes</comment>
+
+ <entry key="1.NameUri">http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier</entry>
+ <entry key="1.FriendlyName">PersonIdentifier</entry>
+ <entry key="1.PersonType">NaturalPerson</entry>
+ <entry key="1.Required">true</entry>
+ <entry key="1.UniqueIdentifier">true</entry>
+ <entry key="1.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="1.XmlType.LocalPart">PersonIdentifierType</entry>
+ <entry key="1.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="1.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="2.NameUri">http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName</entry>
+ <entry key="2.FriendlyName">FamilyName</entry>
+ <entry key="2.PersonType">NaturalPerson</entry>
+ <entry key="2.Required">true</entry>
+ <entry key="2.TransliterationMandatory">true</entry>
+ <entry key="2.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="2.XmlType.LocalPart">CurrentFamilyNameType</entry>
+ <entry key="2.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="2.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="3.NameUri">http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName</entry>
+ <entry key="3.FriendlyName">FirstName</entry>
+ <entry key="3.PersonType">NaturalPerson</entry>
+ <entry key="3.Required">true</entry>
+ <entry key="3.TransliterationMandatory">true</entry>
+ <entry key="3.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="3.XmlType.LocalPart">CurrentGivenNameType</entry>
+ <entry key="3.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="3.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="4.NameUri">http://eidas.europa.eu/attributes/naturalperson/DateOfBirth</entry>
+ <entry key="4.FriendlyName">DateOfBirth</entry>
+ <entry key="4.PersonType">NaturalPerson</entry>
+ <entry key="4.Required">true</entry>
+ <entry key="4.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="4.XmlType.LocalPart">DateOfBirthType</entry>
+ <entry key="4.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="4.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.DateTimeAttributeValueMarshaller</entry>
+
+ <entry key="5.NameUri">http://eidas.europa.eu/attributes/naturalperson/BirthName</entry>
+ <entry key="5.FriendlyName">BirthName</entry>
+ <entry key="5.PersonType">NaturalPerson</entry>
+ <entry key="5.Required">false</entry>
+ <entry key="5.TransliterationMandatory">true</entry>
+ <entry key="5.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="5.XmlType.LocalPart">BirthNameType</entry>
+ <entry key="5.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="5.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="6.NameUri">http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth</entry>
+ <entry key="6.FriendlyName">PlaceOfBirth</entry>
+ <entry key="6.PersonType">NaturalPerson</entry>
+ <entry key="6.Required">false</entry>
+ <entry key="6.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="6.XmlType.LocalPart">PlaceOfBirthType</entry>
+ <entry key="6.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="6.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="7.NameUri">http://eidas.europa.eu/attributes/naturalperson/CurrentAddress</entry>
+ <entry key="7.FriendlyName">CurrentAddress</entry>
+ <entry key="7.PersonType">NaturalPerson</entry>
+ <entry key="7.Required">false</entry>
+ <entry key="7.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="7.XmlType.LocalPart">CurrentAddressType</entry>
+ <entry key="7.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="7.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.CurrentAddressAttributeValueMarshaller</entry>
+
+ <entry key="8.NameUri">http://eidas.europa.eu/attributes/naturalperson/Gender</entry>
+ <entry key="8.FriendlyName">Gender</entry>
+ <entry key="8.PersonType">NaturalPerson</entry>
+ <entry key="8.Required">false</entry>
+ <entry key="8.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="8.XmlType.LocalPart">GenderType</entry>
+ <entry key="8.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="8.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.GenderAttributeValueMarshaller</entry>
+
+ <entry key="9.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier</entry>
+ <entry key="9.FriendlyName">LegalPersonIdentifier</entry>
+ <entry key="9.PersonType">LegalPerson</entry>
+ <entry key="9.Required">true</entry>
+ <entry key="9.UniqueIdentifier">true</entry>
+ <entry key="9.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="9.XmlType.LocalPart">LegalPersonIdentifierType</entry>
+ <entry key="9.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="9.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="10.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalName</entry>
+ <entry key="10.FriendlyName">LegalName</entry>
+ <entry key="10.PersonType">LegalPerson</entry>
+ <entry key="10.Required">true</entry>
+ <entry key="10.TransliterationMandatory">true</entry>
+ <entry key="10.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="10.XmlType.LocalPart">LegalNameType</entry>
+ <entry key="10.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="10.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="11.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalPersonAddress</entry>
+ <entry key="11.FriendlyName">LegalAddress</entry>
+ <entry key="11.PersonType">LegalPerson</entry>
+ <entry key="11.Required">false</entry>
+ <entry key="11.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="11.XmlType.LocalPart">LegalPersonAddressType</entry>
+ <entry key="11.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="11.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.LegalAddressAttributeValueMarshaller</entry>
+
+ <entry key="12.NameUri">http://eidas.europa.eu/attributes/legalperson/VATRegistrationNumber</entry>
+ <entry key="12.FriendlyName">VATRegistration</entry>
+ <entry key="12.PersonType">LegalPerson</entry>
+ <entry key="12.Required">false</entry>
+ <entry key="12.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="12.XmlType.LocalPart">VATRegistrationNumberType</entry>
+ <entry key="12.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="12.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="13.NameUri">http://eidas.europa.eu/attributes/legalperson/TaxReference</entry>
+ <entry key="13.FriendlyName">TaxReference</entry>
+ <entry key="13.PersonType">LegalPerson</entry>
+ <entry key="13.Required">false</entry>
+ <entry key="13.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="13.XmlType.LocalPart">TaxReferenceType</entry>
+ <entry key="13.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="13.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="14.NameUri">http://eidas.europa.eu/attributes/legalperson/D-2012-17-EUIdentifier</entry>
+ <entry key="14.FriendlyName">D-2012-17-EUIdentifier</entry>
+ <entry key="14.PersonType">LegalPerson</entry>
+ <entry key="14.Required">false</entry>
+ <entry key="14.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="14.XmlType.LocalPart">D-2012-17-EUIdentifierType</entry>
+ <entry key="14.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="14.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="15.NameUri">http://eidas.europa.eu/attributes/legalperson/LEI</entry>
+ <entry key="15.FriendlyName">LEI</entry>
+ <entry key="15.PersonType">LegalPerson</entry>
+ <entry key="15.Required">false</entry>
+ <entry key="15.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="15.XmlType.LocalPart">LEIType</entry>
+ <entry key="15.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="15.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="16.NameUri">http://eidas.europa.eu/attributes/legalperson/EORI</entry>
+ <entry key="16.FriendlyName">EORI</entry>
+ <entry key="16.PersonType">LegalPerson</entry>
+ <entry key="16.Required">false</entry>
+ <entry key="16.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="16.XmlType.LocalPart">EORIType</entry>
+ <entry key="16.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="16.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="17.NameUri">http://eidas.europa.eu/attributes/legalperson/SEED</entry>
+ <entry key="17.FriendlyName">SEED</entry>
+ <entry key="17.PersonType">LegalPerson</entry>
+ <entry key="17.Required">false</entry>
+ <entry key="17.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="17.XmlType.LocalPart">SEEDType</entry>
+ <entry key="17.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="17.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="18.NameUri">http://eidas.europa.eu/attributes/legalperson/SIC</entry>
+ <entry key="18.FriendlyName">SIC</entry>
+ <entry key="18.PersonType">LegalPerson</entry>
+ <entry key="18.Required">false</entry>
+ <entry key="18.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="18.XmlType.LocalPart">SICType</entry>
+ <entry key="18.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="18.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="19.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/PersonIdentifier</entry>
+ <entry key="19.FriendlyName">RepresentativePersonIdentifier</entry>
+ <entry key="19.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="19.Required">false</entry>
+ <entry key="19.UniqueIdentifier">true</entry>
+ <entry key="19.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="19.XmlType.LocalPart">PersonIdentifierType</entry>
+ <entry key="19.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="19.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="20.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/CurrentFamilyName</entry>
+ <entry key="20.FriendlyName">RepresentativeFamilyName</entry>
+ <entry key="20.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="20.Required">false</entry>
+ <entry key="20.TransliterationMandatory">true</entry>
+ <entry key="20.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="20.XmlType.LocalPart">CurrentFamilyNameType</entry>
+ <entry key="20.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="20.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="21.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/CurrentGivenName</entry>
+ <entry key="21.FriendlyName">RepresentativeFirstName</entry>
+ <entry key="21.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="21.Required">false</entry>
+ <entry key="21.TransliterationMandatory">true</entry>
+ <entry key="21.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="21.XmlType.LocalPart">CurrentGivenNameType</entry>
+ <entry key="21.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="21.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="22.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth</entry>
+ <entry key="22.FriendlyName">RepresentativeDateOfBirth</entry>
+ <entry key="22.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="22.Required">false</entry>
+ <entry key="22.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="22.XmlType.LocalPart">DateOfBirthType</entry>
+ <entry key="22.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="22.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.DateTimeAttributeValueMarshaller</entry>
+
+ <entry key="23.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/BirthName</entry>
+ <entry key="23.FriendlyName">RepresentativeBirthName</entry>
+ <entry key="23.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="23.Required">false</entry>
+ <entry key="23.TransliterationMandatory">true</entry>
+ <entry key="23.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="23.XmlType.LocalPart">BirthNameType</entry>
+ <entry key="23.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="23.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="24.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/PlaceOfBirth</entry>
+ <entry key="24.FriendlyName">RepresentativePlaceOfBirth</entry>
+ <entry key="24.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="24.Required">false</entry>
+ <entry key="24.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="24.XmlType.LocalPart">PlaceOfBirthType</entry>
+ <entry key="24.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="24.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="25.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/CurrentAddress</entry>
+ <entry key="25.FriendlyName">RepresentativeCurrentAddress</entry>
+ <entry key="25.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="25.Required">false</entry>
+ <entry key="25.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="25.XmlType.LocalPart">CurrentAddressType</entry>
+ <entry key="25.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="25.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.RepvCurrentAddressAttributeValueMarshaller</entry>
+
+ <entry key="26.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/Gender</entry>
+ <entry key="26.FriendlyName">RepresentativeGender</entry>
+ <entry key="26.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="26.Required">false</entry>
+ <entry key="26.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="26.XmlType.LocalPart">GenderType</entry>
+ <entry key="26.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="26.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.GenderAttributeValueMarshaller</entry>
+
+ <entry key="27.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonIdentifier</entry>
+ <entry key="27.FriendlyName">RepresentativeLegalPersonIdentifier</entry>
+ <entry key="27.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="27.Required">false</entry>
+ <entry key="27.UniqueIdentifier">true</entry>
+ <entry key="27.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="27.XmlType.LocalPart">LegalPersonIdentifierType</entry>
+ <entry key="27.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="27.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="28.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalName</entry>
+ <entry key="28.FriendlyName">RepresentativeLegalName</entry>
+ <entry key="28.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="28.Required">false</entry>
+ <entry key="28.TransliterationMandatory">true</entry>
+ <entry key="28.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="28.XmlType.LocalPart">LegalNameType</entry>
+ <entry key="28.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="28.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="29.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonAddress</entry>
+ <entry key="29.FriendlyName">RepresentativeLegalAddress</entry>
+ <entry key="29.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="29.Required">false</entry>
+ <entry key="29.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="29.XmlType.LocalPart">LegalPersonAddressType</entry>
+ <entry key="29.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="29.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.RepvLegalAddressAttributeValueMarshaller</entry>
+
+ <entry key="30.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/VATRegistrationNumber</entry>
+ <entry key="30.FriendlyName">RepresentativeVATRegistration</entry>
+ <entry key="30.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="30.Required">false</entry>
+ <entry key="30.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="30.XmlType.LocalPart">VATRegistrationNumberType</entry>
+ <entry key="30.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="30.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="31.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/TaxReference</entry>
+ <entry key="31.FriendlyName">RepresentativeTaxReference</entry>
+ <entry key="31.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="31.Required">false</entry>
+ <entry key="31.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="31.XmlType.LocalPart">TaxReferenceType</entry>
+ <entry key="31.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="31.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="32.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/D-2012-17-EUIdentifier</entry>
+ <entry key="32.FriendlyName">RepresentativeD-2012-17-EUIdentifier</entry>
+ <entry key="32.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="32.Required">false</entry>
+ <entry key="32.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="32.XmlType.LocalPart">D-2012-17-EUIdentifierType</entry>
+ <entry key="32.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="32.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="33.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LEI</entry>
+ <entry key="33.FriendlyName">RepresentativeLEI</entry>
+ <entry key="33.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="33.Required">false</entry>
+ <entry key="33.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="33.XmlType.LocalPart">LEIType</entry>
+ <entry key="33.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="33.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="34.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/EORI</entry>
+ <entry key="34.FriendlyName">RepresentativeEORI</entry>
+ <entry key="34.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="34.Required">false</entry>
+ <entry key="34.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="34.XmlType.LocalPart">EORIType</entry>
+ <entry key="34.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="34.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="35.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/SEED</entry>
+ <entry key="35.FriendlyName">RepresentativeSEED</entry>
+ <entry key="35.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="35.Required">false</entry>
+ <entry key="35.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="35.XmlType.LocalPart">SEEDType</entry>
+ <entry key="35.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="35.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="36.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/SIC</entry>
+ <entry key="36.FriendlyName">RepresentativeSIC</entry>
+ <entry key="36.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="36.Required">false</entry>
+ <entry key="36.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="36.XmlType.LocalPart">SICType</entry>
+ <entry key="36.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="36.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="39.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonAddress</entry>
+ <entry key="39.FriendlyName">RepresentativeLegalAddress</entry>
+ <entry key="39.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="39.Required">false</entry>
+ <entry key="39.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="39.XmlType.LocalPart">LegalPersonAddressType</entry>
+ <entry key="39.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="39.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.RepvLegalAddressAttributeValueMarshaller</entry>
+
+ <entry key="40.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/VATRegistrationNumber</entry>
+ <entry key="40.FriendlyName">RepresentativeVATRegistration</entry>
+ <entry key="40.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="40.Required">false</entry>
+ <entry key="40.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="40.XmlType.LocalPart">VATRegistrationNumberType</entry>
+ <entry key="40.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="40.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+
+</properties>
diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json
new file mode 100644
index 00000000..96034d12
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/config/idaAttributeMapping.json
@@ -0,0 +1,215 @@
+[
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier",
+ "idaAttribute": {
+ "basic": "urn:oid:1.2.40.0.10.2.1.1.149",
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.98"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName",
+ "idaAttribute": {
+ "basic": "urn:oid:2.5.4.42",
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.78"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName",
+ "idaAttribute": {
+ "basic": "urn:oid:1.2.40.0.10.2.1.1.261.20",
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.80"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth",
+ "idaAttribute": {
+ "basic": "urn:oid:1.2.40.0.10.2.1.1.55",
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.82"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth",
+ "idaAttribute": {},
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/BirthName",
+ "idaAttribute": {
+ "basic": "ida_birthname",
+ "withMandates": "ida_birthName_mandator"
+ },
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.100"
+ },
+ "addionalRequiredAttributes" : [
+ "urn:oid:1.2.40.0.10.2.1.1.149",
+ "urn:oid:2.5.4.42",
+ "urn:oid:1.2.40.0.10.2.1.1.261.20",
+ "urn:oid:1.2.40.0.10.2.1.1.55"
+ ],
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/legalperson/LegalName",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.84"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/PersonIdentifier",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.149"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": true
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/CurrentFamilyName",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.20"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": true
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/CurrentGivenName",
+ "idaAttribute": {
+ "withMandates": "urn:oid:2.5.4.42"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": true
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.55"
+ },
+ "type": {
+ "mds": true,
+ "autoIncludeWithMandates": true
+ }
+ },
+ {
+ "eidasAttribute": "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole",
+ "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler",
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole",
+ "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.EJusticePersonRoleHandler",
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://e-justice.europa.eu/attributes/legalperson/eJusticePersonRoleNotExist",
+ "specificAttributeHandlerClass": "at.asitplus.eidas.specific.modules.msproxyservice.handler.notExist",
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "*",
+ "idaAttribute": {
+ "basic": "urn:oid:1.2.40.0.10.2.1.1.261.32",
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.32"
+ },
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "*",
+ "idaAttribute": {
+ "basic": "urn:oid:1.2.40.0.10.2.1.1.261.108",
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.108"
+ },
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "*",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.68"
+ },
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "*",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.106"
+ },
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/jUnit/not/exits",
+ "idaAttribute": {
+ "withMandates": "urn:oid:1.2.40.0.10.2.1.1.261.106"
+ },
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ },
+ {
+ "eidasAttribute": "http://eidas.europa.eu/attributes/jUnit/no/custom/handler",
+ "specificAttributeHandlerClass": "",
+ "type": {
+ "mds": false,
+ "autoIncludeWithMandates": false
+ }
+ }
+] \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties
new file mode 100644
index 00000000..90b44868
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties
@@ -0,0 +1,19 @@
+## Basic service configuration
+eidas.ms.context.url.prefix=http://localhost
+eidas.ms.context.url.request.validation=false
+
+eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy
+eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint
+
+eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json
+
+
+#############################################################################
+## advanced eIDAS attribute processing
+
+# BORIS attribute for eJustice
+eidas.ms.advanced.attributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED
+eidas.ms.advanced.attributes.ejusticerole.mandate.mode=legal
+eidas.ms.advanced.attributes.ejusticerole.additional.ida.attributes=testAttribute
+eidas.ms.advanced.attributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1
+eidas.ms.advanced.attributes.ejusticerole.value.2=SECOND=VIP2
diff --git a/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties
new file mode 100644
index 00000000..8963129e
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/config/junit_config_2.properties
@@ -0,0 +1,18 @@
+## Basic service configuration
+eidas.ms.context.url.prefix=http://localhost
+eidas.ms.context.url.request.validation=false
+
+eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy
+eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint
+
+eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=idaAttributeMapping.json
+
+
+#############################################################################
+## advanced eIDAS attribute processing
+
+# BORIS attribute for eJustice
+eidas.ms.advanced.attributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED
+eidas.ms.advanced.attributes.ejusticerole.mandate.mode=legal
+eidas.ms.advanced.attributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1
+eidas.ms.advanced.attributes.ejusticerole.value.2=SECOND=VIP2
diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml
new file mode 100644
index 00000000..fe9ff441
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig.xml
@@ -0,0 +1,20 @@
+<?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">
+
+ <context:annotation-config />
+
+ <bean id="dummyMapBasedConfiguration"
+ class="at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap">
+ <constructor-arg value="/config/junit_config_1.properties" />
+ <property name="configRootDirSufix" value="src/test/resources/config" />
+ </bean>
+
+</beans> \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml
new file mode 100644
index 00000000..dfe98ea5
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_mapConfig2.xml
@@ -0,0 +1,20 @@
+<?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">
+
+ <context:annotation-config />
+
+ <bean id="dummyMapBasedConfiguration"
+ class="at.asitplus.eidas.specific.core.test.config.dummy.MsConnectorDummyConfigMap">
+ <constructor-arg value="/config/junit_config_2.properties" />
+ <property name="configRootDirSufix" value="src/test/resources/config" />
+ </bean>
+
+</beans> \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml
new file mode 100644
index 00000000..0b7540f5
--- /dev/null
+++ b/modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml
@@ -0,0 +1,34 @@
+<?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="classpath:/SpringTest-context_authManager.xml" />
+ <import resource="classpath:/spring/eidas_proxy-service.beans.xml"/>
+
+ <bean id="springManagedSpecificProxyserviceCommunicationService"
+ class="at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService" />
+
+ <bean id="mvcGUIBuilderImpl"
+ class="at.gv.egiz.eaaf.core.impl.gui.builder.SpringMvcGuiFormBuilderImpl" />
+
+ <bean id="specificConnectorAttributesFileWithPath"
+ class="java.lang.String">
+ <constructor-arg
+ value="src/test/resources/config/eidas-attributes.xml" />
+ </bean>
+
+ <bean id="specificConnectorAdditionalAttributesFileWithPath"
+ class="java.lang.String">
+ <constructor-arg
+ value="src/test/resources/config/additional-attributes.xml" />
+ </bean>
+
+</beans> \ No newline at end of file
diff --git a/modules/pom.xml b/modules/pom.xml
index 0c82392a..6d6d2ca2 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -15,7 +15,10 @@
<modules>
<module>core_common_lib</module>
<module>core_common_webapp</module>
- <module>authmodule-eIDAS-v2</module>
+ <module>authmodule-eIDAS-v2</module>
+ <module>authmodule_id-austria</module>
+ <module>eidas_proxy-sevice</module>
+ <module>core_commons_eidas</module>
</modules>
</project>