diff options
15 files changed, 560 insertions, 69 deletions
diff --git a/README.md b/README.md new file mode 100644 index 00000000..e0914598 --- /dev/null +++ b/README.md @@ -0,0 +1,112 @@ +# Member-state specific eIDAS Application + +## Description + +The member-state specific eIDAS application (ms-specific eIDAS) implements the bridge between the eIDAS reference implementation provides by European commission and the national eID system. This application consists of two parts + +- **MS-specific Connector:** implements the bridge to connect a national service-provider to a foreign idenity-provider. + +- **MS-specific Proxy-Service:** implements the bridge to connect a foreign service-provider to national eID system (ID Austria). This feature is not implemented yet. + + + +### Building + +The application uses SpringBoot as core framework, but the default build-profile does not build an executable jar. There, the application has to be deployed into an application service, like Apache Tomcat + +The project can be build with : + +``` +mvn clean package +``` + +The resulting `war` file can be deployed into an application server + +Set Java System-Property _-Deidas.ms.configuration=/path/to/configuration..._ to set the configuration for this application + + + +If you like to build an executable SpringBoot application with embedded Tomcat then use: + +``` +mvn -P embbededTomcat clean package +``` + +The resulting `jar` file can be run with java: + +``` +java -jar ./connector/target/ms-connector.jar +``` + +But it is also directly executalbe + +``` +./connector/target/ms-connector.jar +``` + +In case of a executable application package, the configuration can be either set by Java System-Property _-Deidas.ms.configuration=/path/to/configuration..._ or by default SpringBoot configuration features. + + + +### Configuration + +A default configuration is located at _basicConfig/_ + + + +## Generate a BM.I Release Package + +The full release packages for BM.I infrastructure will be automatically assembled by maven build-process. Before release build, all release related information have to added into infos folder. To add release informations follow the steps outlined below. + +Add a file with release informations to: +``` +./infos/readme_{version}.txt +``` + +Add additional eIDAS Node related information into: + +``` +./infos/eIDAS_Ref_Impl/ +``` + +Add, remove, or update the application description in the handbook and store the handbook for the current release version as pdf. + +``` +modify: ./infos/handbook-work_in_progress.docx +store pdf to: ./infos/handbook/handbook-{version}.pdf +``` + +Generate a release package with: + + +``` +mvn clean package +``` + +The full release package will be located add +``` +./target/ms_specific_connector-{version}-dist.tar.gz +``` + + + +## Changelog + +**v1.2.0** + +- Anpassungen zur Anbindungen an das E-ID System +- Update auf eIDAS Ref. Impl. 2.5.0 mit Apache Ignite Cache + https://ec.europa.eu/cefdigital/wiki/display/CEFDIGITAL/eIDAS-Node+version+2.5 +- TODO: + + + +**v1.1.0** + + - Update auf eIDAS Ref. Impl. 2.4.0 mit Apache Ignite Cache + https://ec.europa.eu/cefdigital/wiki/display/CEFDIGITAL/eIDAS-Node+version+2.4 + - Statischer Service-Provider Name für öffentliche Applikationen + - Mindest LoA, welche für Requests an eIDAS Proxy-Services verwendet wird. + - Requested Attributes je Land konfigurierbar + - Neue Template-Engine mit i18n Unterstützung + - Neuer Algorithmus zur Generierung von Sessiontokens
\ No newline at end of file diff --git a/basicConfig/default_config.properties b/basicConfig/default_config.properties index 8a1bc3a0..725fac7c 100644 --- a/basicConfig/default_config.properties +++ b/basicConfig/default_config.properties @@ -1,6 +1,5 @@ ## Basic service configuration eidas.ms.context.url.prefix= -eidas.ms.context.url.request.validation=false eidas.ms.core.configRootDir=file:./ @@ -31,6 +30,9 @@ eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.password= eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.path= eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.password= +## eIDAS Request configuration +eidas.ms.auth.eIDAS.node_v2.staticProviderNameForPublicSPs=Austria + ## E-AuthBlock configuration eidas.ms.auth.eIDAS.authblock.keystore.type=jks diff --git a/connector/src/assembly/assembly_dir.xml b/connector/src/assembly/assembly_dir.xml index 37e05390..59437be6 100644 --- a/connector/src/assembly/assembly_dir.xml +++ b/connector/src/assembly/assembly_dir.xml @@ -43,7 +43,9 @@ <includes> <!-- include>README.md</include--> <include>readme_${project.version}.txt</include> + <include>readme_${project.version}.md</include> <include>eIDAS_Ref_Impl/*</include> + <include>handbook/*</include> </includes> </fileSet> </fileSets> diff --git a/connector/src/assembly/assembly_zip.xml b/connector/src/assembly/assembly_zip.xml index 579da2e1..43877283 100644 --- a/connector/src/assembly/assembly_zip.xml +++ b/connector/src/assembly/assembly_zip.xml @@ -43,6 +43,9 @@ <includes> <!-- include>README.md</include --> <include>readme_${project.version}.txt</include> + <include>readme_${project.version}.md</include> + <include>eIDAS_Ref_Impl/*</include> + <include>handbook/*</include> </includes> </fileSet> </fileSets> diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties index b13b6c18..9a4ae54f 100644 --- a/connector/src/main/resources/application.properties +++ b/connector/src/main/resources/application.properties @@ -17,9 +17,9 @@ spring.boot.admin.client.enabled=false ############################################################################# ## MS-speccific eIDAS-Connector configuration -#proxy.context.url.prefix= +#eidas.ms.context.url.prefix= eidas.ms.context.url.request.validation=false -#proxy.configRootDir=file:/.../config/ +#eidas.ms.configRootDir=file:/.../config/ eidas.ms.context.use.clustermode=true eidas.ms.core.logging.level.info.errorcodes=auth.21 @@ -51,10 +51,22 @@ eidas.ms.auth.eIDAS.node_v2.entityId=ownSpecificConnector #eidas.ms.auth.eIDAS.node_v2.forward.endpoint= eidas.ms.auth.eIDAS.node_v2.forward.method=POST eidas.ms.auth.eIDAS.node_v2.countrycode=AT -eidas.ms.auth.eIDAS.node_v2.publicSectorTargets=.* -eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName=true +eidas.ms.auth.eIDAS.node_v2.publicSectorTargets=urn:publicid:gv.at:cdid\+.* + +## use SAML2 requestId as transactionIdentifier to mitigate problems with SAML2 relaystate eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier=true -eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs=true + +## use hashed version of unique SP-Identifier as requesterId +eidas.ms.auth.eIDAS.node_v2.requesterId.useHashedForm=true + +## user static requesterId for all SP's in case of LU +eidas.ms.auth.eIDAS.node_v2.requesterId.lu.useStaticRequesterForAll=true + + +## set provider name for all public SPs +eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName=false + + eidas.ms.auth.eIDAS.node_v2.loa.requested.minimum=http://eidas.europa.eu/LoA/high @@ -92,6 +104,7 @@ eidas.ms.auth.eIDAS.szrclient.params.setBirthNameIfAvailable=true eidas.ms.auth.eIDAS.szrclient.debug.logfullmessages=false eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution=false + ##without mandates eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.0=PersonIdentifier,true eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.1=FamilyName,true @@ -120,7 +133,7 @@ eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.5=LegalName,true #eidas.ms.pvp2.key.metadata.password=password #eidas.ms.pvp2.key.signing.alias=sig #eidas.ms.pvp2.key.signing.password=password -#eidas.ms.pvp2.metadata.validity=24 +eidas.ms.pvp2.metadata.validity=24 #eidas.ms.pvp2.metadata.organisation.name=JUnit #eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit @@ -141,8 +154,6 @@ eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.5=LegalName,true ##only for advanced config -eidas.ms.configuration.sp.disableRegistrationRequirement= -#eidas.ms.configuration.restrictions.baseID.spTransmission= -eidas.ms.configuration.auth.default.countrycode= -eidas.ms.configuration.pvp.scheme.validation= -eidas.ms.configuration.pvp.enable.entitycategories=
\ No newline at end of file +eidas.ms.configuration.sp.disableRegistrationRequirement=false +eidas.ms.configuration.pvp.scheme.validation=true +eidas.ms.configuration.pvp.enable.entitycategories=false
\ No newline at end of file diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java index cdc17654..c175d999 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java @@ -56,15 +56,21 @@ public class Constants { 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"; + + public static final String CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION = + 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"; + public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME = - CONIG_PROPS_EIDAS_NODE + ".workarounds.addAlwaysProviderName"; + CONIG_PROPS_EIDAS_NODE + ".workarounds.addAlwaysProviderName"; public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER = CONIG_PROPS_EIDAS_NODE + ".workarounds.useRequestIdAsTransactionIdentifier"; - public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP = - CONIG_PROPS_EIDAS_NODE + ".workarounds.useStaticProviderNameForPublicSPs"; + + public static final String CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP = CONIG_PROPS_EIDAS_NODE + ".staticProviderNameForPublicSPs"; - public static final String DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP = "ERnP"; + public static final String DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP = "Austria"; public static final String FORWARD_METHOD_POST = "POST"; public static final String FORWARD_METHOD_GET = "GET"; diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java index 42dbfeac..90be9a7a 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java @@ -23,6 +23,10 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -66,7 +70,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor { public final void preProcess(IRequest pendingReq, Builder authnRequestBuilder) { buildLevelOfAssurance(pendingReq.getServiceProviderConfiguration(), authnRequestBuilder); - buildProviderNameAttribute(pendingReq, authnRequestBuilder); + buildProviderNameAndRequesterIdAttribute(pendingReq, authnRequestBuilder); buildRequestedAttributes(authnRequestBuilder); } @@ -272,6 +276,83 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor { } + /** + * Set ProviderName and RequestId into eIDAS AuthnRequest. + * + * @param pendingReq Current pendingRequest + * @param authnRequestBuilder AuthnREquest builer + */ + protected void buildProviderNameAndRequesterIdAttribute(IRequest pendingReq, Builder authnRequestBuilder) { + final ISpConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); + + // set correct SPType for requested target sector + final String publicSectorTargetSelector = basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS, + Constants.POLICY_DEFAULT_ALLOWED_TARGETS); + final Pattern p = Pattern.compile(publicSectorTargetSelector); + final Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier()); + if (m.matches()) { + log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'"); + authnRequestBuilder.spType(SpType.PUBLIC.getValue()); + + final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); + if (basicConfig.getBasicConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, + false)) { + //TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for + if (StringUtils.isNotEmpty(providerName)) { + log.debug("Set 'providername' to: {}", providerName); + authnRequestBuilder.providerName(providerName); + + } else { + authnRequestBuilder.providerName(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP, + Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP)); + + } + } + + } else { + log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PrivateSector'"); + authnRequestBuilder.spType(SpType.PRIVATE.getValue()); + + // TODO: switch to RequesterId in further version + // set provider name for private sector applications + final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); + if (StringUtils.isNotEmpty(providerName)) { + authnRequestBuilder.providerName(providerName); + + } + + authnRequestBuilder.requesterId( + generateRequesterId(pendingReq.getRawData(Constants.DATA_REQUESTERID, String.class))); + + } + } + + private String generateRequesterId(String requesterId) { + if (requesterId != null && basicConfig.getBasicConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION, true)) { + try { + log.trace("Building hashed 'requesterId' for private SP ... "); + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + String encodedRequesterId = Base64.getEncoder().encodeToString( + digest.digest(requesterId.getBytes(StandardCharsets.UTF_8))); + log.debug("Set 'requesterId' for: {} to: {}", requesterId, encodedRequesterId); + return encodedRequesterId; + + } catch (NoSuchAlgorithmException e) { + log.error("Can NOT generate hashed 'requesterId' from: {}. Use it as it is", requesterId, e); + + } + + } + + return requesterId; + + } + + private void buildRequestedAttributes(Builder authnRequestBuilder) { // build and add requested attribute set final Map<String, Boolean> ccSpecificReqAttr = getCountrySpecificRequestedAttributes(); @@ -308,55 +389,6 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor { return builder.build(); } - - private void buildProviderNameAttribute(IRequest pendingReq, Builder authnRequestBuilder) { - final ISpConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); - - // set correct SPType for requested target sector - final String publicSectorTargetSelector = basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS, - Constants.POLICY_DEFAULT_ALLOWED_TARGETS); - final Pattern p = Pattern.compile(publicSectorTargetSelector); - final Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier()); - if (m.matches()) { - log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'"); - authnRequestBuilder.spType(SpType.PUBLIC.getValue()); - - if (basicConfig.getBasicConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP, - true)) { - authnRequestBuilder.providerName(basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP, - Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP)); - - } else { - // TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for - // any SPType - final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); - if (StringUtils.isNotEmpty(providerName) - && basicConfig.getBasicConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, - false)) { - authnRequestBuilder.providerName(providerName); - - } - } - - } else { - log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PrivateSector'"); - authnRequestBuilder.spType(SpType.PRIVATE.getValue()); - - // TODO: switch to RequesterId in further version - // set provider name for private sector applications - final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); - if (StringUtils.isNotEmpty(providerName)) { - authnRequestBuilder.providerName(providerName); - authnRequestBuilder.requesterId(providerName); - - } - - } - } private void buildLevelOfAssurance(ISpConfiguration spConfig, Builder authnRequestBuilder) { // TODO: set matching mode if eIDAS ref. impl. support this method diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java new file mode 100644 index 00000000..8402457f --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java @@ -0,0 +1,61 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler; + +import java.util.HashMap; +import java.util.Map; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.gv.egiz.eaaf.core.api.IRequest; +import eu.eidas.auth.commons.light.impl.LightRequest.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class LuEidProcessor extends AbstractEidProcessor { + + + + private static final String canHandleCC = "LU"; + + @Getter + @Setter + private int priority = 1; + + @Override + public String getName() { + return "LU-PostProcessor"; + + } + + @Override + public boolean canHandle(String countryCode) { + return countryCode != null && countryCode.equalsIgnoreCase(canHandleCC); + + } + + @Override + protected void buildProviderNameAndRequesterIdAttribute(IRequest pendingReq, Builder authnRequestBuilder) { + super.buildProviderNameAndRequesterIdAttribute(pendingReq, authnRequestBuilder); + if (basicConfig.getBasicConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_REQUESTERID_FOR_LUX, true)) { + String staticName = basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP, + Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP); + authnRequestBuilder.providerName(staticName); + authnRequestBuilder.requesterId(staticName); + log.debug("Use static name: {} as 'providerName' and 'RequesterId' for all 'LU' requests ", staticName); + + } else { + log.info("Static 'providerName' and 'RequesterId' for country: LU is deactivated"); + + } + + } + + @Override + protected Map<String, Boolean> getCountrySpecificRequestedAttributes() { + return new HashMap<>(); + + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml index 6cc704ab..3b0cee54 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml @@ -69,6 +69,11 @@ <property name="priority" value="1" /> </bean> + <bean id="LU-Processor" + class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.LuEidProcessor"> + <property name="priority" value="1" /> + </bean> + <bean id="Default-Processor" class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.GenericEidProcessor"> <property name="priority" value="0" /> diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java index c416b515..f796bd86 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java @@ -83,6 +83,7 @@ public class GenerateAuthnRequestTaskTest { pendingReq.setPendingReqId(at.gv.egiz.eaaf.core.impl.utils.Random.nextProcessReferenceValue()); pendingReq.setAuthUrl("http://test.com/"); + basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.requesterId.useHashedForm", "true"); basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.entityId", RandomStringUtils.randomAlphabetic(10)); basicConfig.putConfigValue( @@ -297,7 +298,7 @@ public class GenerateAuthnRequestTaskTest { basicConfig.putConfigValue( "eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier", "true"); basicConfig.putConfigValue( - "eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs", "true"); + "eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderNames", "true"); basicConfig.putConfigValue( "eidas.ms.auth.eIDAS.node_v2.staticProviderNameForPublicSPs", "myNode"); @@ -366,6 +367,101 @@ public class GenerateAuthnRequestTaskTest { } @Test + public void publicSpWithCountryLu() throws TaskExecutionException, + SpecificCommunicationException, EaafStorageException, UnsupportedEncodingException { + //set-up test + executionContext.put(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY, "LU"); + executionContext.put("selectedEnvironment", "prod"); + + String providerName = RandomStringUtils.randomAlphanumeric(10); + pendingReq.setRawDataToTransaction(Constants.DATA_PROVIDERNAME, providerName); + + basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.publicSectorTargets"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName", "true"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier", "true"); + + String dynEndPoint = "http://test/" + RandomStringUtils.randomAlphabetic(5); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.forward.endpoint", dynEndPoint); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.forward.method", "GET"); + + //execute test + task.execute(pendingReq, executionContext); + + //validate state + Assert.assertEquals("Wrong http statusCode", 302, httpResp.getStatus()); + Assert.assertNotNull("No redirect header", httpResp.getHeaderValue("Location")); + Assert.assertTrue("Wrong redirect endpoint", + ((String) httpResp.getHeaderValue("Location")).startsWith(dynEndPoint)); + + + final ILightRequest eidasReq = commService.getAndRemoveRequest(null, null); + + Assert.assertEquals("PrividerName", "myNode", eidasReq.getProviderName()); + Assert.assertEquals("RequesterId found", "myNode", eidasReq.getRequesterId()); + Assert.assertEquals("no PublicSP", "public", eidasReq.getSpType()); + Assert.assertEquals("wrong LoA", EaafConstants.EIDAS_LOA_HIGH, + eidasReq.getLevelOfAssurance()); + + Assert.assertEquals("Wrong req. attr. size", 4, eidasReq.getRequestedAttributes().size()); + + } + + @Test + public void privateSpWithCountryLu() throws TaskExecutionException, + SpecificCommunicationException, EaafStorageException, UnsupportedEncodingException { + //set-up test + executionContext.put(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY, "LU"); + executionContext.put("selectedEnvironment", "prod"); + + String providerName = RandomStringUtils.randomAlphanumeric(10); + String requesterId = RandomStringUtils.randomAlphanumeric(10); + pendingReq.setRawDataToTransaction(Constants.DATA_PROVIDERNAME, providerName); + pendingReq.setRawDataToTransaction(Constants.DATA_REQUESTERID, requesterId); + + spConfig.put("target", + EaafConstants.URN_PREFIX_WBPK_TARGET_WITH_X + "FN+" + RandomStringUtils.randomNumeric(6)); + + basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.publicSectorTargets"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName", "true"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier", "true"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs", "true"); + + String dynEndPoint = "http://test/" + RandomStringUtils.randomAlphabetic(5); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.forward.endpoint", dynEndPoint); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.forward.method", "GET"); + + //execute test + task.execute(pendingReq, executionContext); + + //validate state + Assert.assertEquals("Wrong http statusCode", 302, httpResp.getStatus()); + Assert.assertNotNull("No redirect header", httpResp.getHeaderValue("Location")); + Assert.assertTrue("Wrong redirect endpoint", + ((String) httpResp.getHeaderValue("Location")).startsWith(dynEndPoint)); + + + final ILightRequest eidasReq = commService.getAndRemoveRequest(null, null); + + Assert.assertEquals("PrividerName", "myNode", eidasReq.getProviderName()); + Assert.assertEquals("RequesterId", "myNode", eidasReq.getRequesterId()); + Assert.assertEquals("no PublicSP", "private", eidasReq.getSpType()); + Assert.assertEquals("wrong LoA", EaafConstants.EIDAS_LOA_HIGH, + eidasReq.getLevelOfAssurance()); + + Assert.assertEquals("Wrong req. attr. size", 4, eidasReq.getRequestedAttributes().size()); + + } + + @Test public void withEidasNodePostReqNotValidTemplate() throws TaskExecutionException, SpecificCommunicationException, EaafStorageException, UnsupportedEncodingException { //set-up test @@ -409,6 +505,53 @@ public class GenerateAuthnRequestTaskTest { EaafConstants.URN_PREFIX_WBPK_TARGET_WITH_X + "FN+" + RandomStringUtils.randomNumeric(6)); String providerName = RandomStringUtils.randomAlphanumeric(10); pendingReq.setRawDataToTransaction(Constants.DATA_PROVIDERNAME, providerName); + pendingReq.setRawDataToTransaction(Constants.DATA_REQUESTERID, "http://junit.sp"); + + basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.publicSectorTargets"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName", "true"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier", "true"); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs", "false"); + + String dynEndPoint = "http://test/" + RandomStringUtils.randomAlphabetic(5); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.forward.endpoint", dynEndPoint); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.forward.method", "GET"); + + + //perform test + task.execute(pendingReq, executionContext); + + //validate state + Assert.assertEquals("Wrong http statusCode", 302, httpResp.getStatus()); + Assert.assertNotNull("No redirect header", httpResp.getHeaderValue("Location")); + Assert.assertTrue("Wrong redirect endpoint", + ((String) httpResp.getHeaderValue("Location")).startsWith(dynEndPoint)); + + + final ILightRequest eidasReq = commService.getAndRemoveRequest(null, null); + + Assert.assertEquals("PrividerName", providerName, eidasReq.getProviderName()); + Assert.assertEquals("RequesterId", "Wr8LrrVf5SYneblOlZdZNaLQQCCgzklfKQvyeZjBx10=", eidasReq.getRequesterId()); + Assert.assertEquals("no PublicSP", "private", eidasReq.getSpType()); + Assert.assertEquals("wrong LoA", "http://eidas.europa.eu/LoA/high", eidasReq.getLevelOfAssurance()); + + } + + @Test + public void privateSPWithoutRequestIdHashing() throws TaskExecutionException, + SpecificCommunicationException, EaafStorageException { + //set-up test + executionContext.put(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY, "CC"); + spConfig.put("target", + EaafConstants.URN_PREFIX_WBPK_TARGET_WITH_X + "FN+" + RandomStringUtils.randomNumeric(6)); + String providerName = RandomStringUtils.randomAlphanumeric(10); + String requesterId = RandomStringUtils.randomAlphanumeric(10); + pendingReq.setRawDataToTransaction(Constants.DATA_PROVIDERNAME, providerName); + pendingReq.setRawDataToTransaction(Constants.DATA_REQUESTERID, requesterId); basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.publicSectorTargets"); basicConfig.putConfigValue( @@ -417,6 +560,7 @@ public class GenerateAuthnRequestTaskTest { "eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier", "true"); basicConfig.putConfigValue( "eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs", "false"); + basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.requesterId.useHashedForm", "false"); String dynEndPoint = "http://test/" + RandomStringUtils.randomAlphabetic(5); basicConfig.putConfigValue( @@ -438,7 +582,7 @@ public class GenerateAuthnRequestTaskTest { final ILightRequest eidasReq = commService.getAndRemoveRequest(null, null); Assert.assertEquals("PrividerName", providerName, eidasReq.getProviderName()); - Assert.assertEquals("RequesterId", providerName, eidasReq.getRequesterId()); + Assert.assertEquals("RequesterId", requesterId, eidasReq.getRequesterId()); Assert.assertEquals("no PublicSP", "private", eidasReq.getSpType()); Assert.assertEquals("wrong LoA", "http://eidas.europa.eu/LoA/high", eidasReq.getLevelOfAssurance()); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java index d0ab50f4..7ac41500 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java @@ -146,9 +146,10 @@ public class EidasRequestPreProcessingFirstTest { Assert.assertEquals("ProviderName is not Static", Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP, lightReq.getProviderName()); + Assert.assertNotSame("RequesterId was set", lightReq.getRequesterId()); Assert.assertEquals("no PublicSP", "public", lightReq.getSpType()); Assert.assertEquals("Requested attribute size not match", 8, lightReq.getRequestedAttributes().size()); } - + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingSecondTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingSecondTest.java index c44e803b..4a03fac1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingSecondTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingSecondTest.java @@ -86,6 +86,9 @@ public class EidasRequestPreProcessingSecondTest { authnRequestBuilder.issuer("Test"); authnRequestBuilder.levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH); + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.requesterId.lu.useStaticRequesterForAll", "true"); + } @Test @@ -106,4 +109,49 @@ public class EidasRequestPreProcessingSecondTest { } + + /* + * Set ProviderName according to general configuration + */ + @Test + public void prePreProcessLuPublicSpWithoutRequestId() throws EidPostProcessingException { + + basicConfig.putConfigValue( + "eidas.ms.auth.eIDAS.node_v2.requesterId.lu.useStaticRequesterForAll", "false"); + + final String testCountry = "LU"; + authnRequestBuilder.citizenCountryCode(testCountry); + preProcessor.preProcess(testCountry, pendingReq, authnRequestBuilder); + + final LightRequest lightReq = authnRequestBuilder.build(); + + Assert.assertEquals("ProviderName is not Static", "myNode", lightReq.getProviderName()); + Assert.assertNull("RequesterId", lightReq.getRequesterId()); + Assert.assertEquals("no PublicSP", "public", lightReq.getSpType()); + Assert.assertEquals("Requested attribute size not match", 4, lightReq.getRequestedAttributes().size()); + + } + + /* + * Always set requesterId and providername in case of country LU + */ + @Test + public void prePreProcessLuPublicSpWithStaticRequesterId() throws EidPostProcessingException { + + + final String testCountry = "LU"; + authnRequestBuilder.citizenCountryCode(testCountry); + preProcessor.preProcess(testCountry, pendingReq, authnRequestBuilder); + + final LightRequest lightReq = authnRequestBuilder.build(); + + Assert.assertEquals("ProviderName is not Static", + "myNode", lightReq.getProviderName()); + Assert.assertEquals("RequesterId is not Static", + "myNode", lightReq.getRequesterId()); + Assert.assertEquals("no PublicSP", "public", lightReq.getSpType()); + Assert.assertEquals("Requested attribute size not match", 4, lightReq.getRequestedAttributes().size()); + + } + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml index 956cfcc9..cd2888c1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml @@ -50,6 +50,11 @@ <property name="priority" value="1" /> </bean> + <bean id="LU-PostProcessor" + class="at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.LuEidProcessor"> + <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/infos/handbook-work_in_progress.docx b/infos/handbook-work_in_progress.docx Binary files differnew file mode 100644 index 00000000..d311fa80 --- /dev/null +++ b/infos/handbook-work_in_progress.docx diff --git a/infos/readme_1.2.0.md b/infos/readme_1.2.0.md new file mode 100644 index 00000000..98e18ccb --- /dev/null +++ b/infos/readme_1.2.0.md @@ -0,0 +1,59 @@ +# MS-Connector v1.2.0 Release vom xx.xx.2021 + +Der MS-Connector implementiert eine Bridge zwischen dem österreichischen E-ID System und dem eIDAS Framework um ausländischen Benutzern eine Anmeldung am österreichischen Service-Providern zu ermöglichen. + +### Änderungen in dieser Version + + - Erforderliche Anpassungen zur Integration in den ID Austria + + - Update auf eIDAS Ref. Impl. 2.5.0 (Implementiert eIDAS Spezifikation 1.2) + https://ec.europa.eu/cefdigital/wiki/display/CEFDIGITAL/eIDAS-Node+version+2.5 + + - Codestabilisierung + + - Monitoring und HealthChecks Verbesserungen + + - Akutalisierung von Drittherstellerbibliotheken + + + + +### Durchführen eines Updates + +Nachfolgend finden Sie die erforderlichen Schritte für das Update eines bestehenden MS-specific eIDAS Connectors auf die aktuelle Version 1.2.0. Das vollständige Handbuch mit allen Konfigurationsparametern finden Sie im Releasepackage im Verzeichnis: _infos/handbook/_ + +### Ausgehend von einer bestehenden Version 1.1.0 + +1. Stoppen Sie die *MS-Connector* Applikation und fertigen Sie eine Sicherungskopie Ihrer Applikation inklusive Konfiguration an +2. Entpacken Sie das Releasepacket *ms_specific_connector-1.2.0-dist.zip* in ein temporäres Verzeichnis welches in weiterer Folge __MsConnectorPackage__ bezeichnet wird. +3. Kopieren sie die Applikation __MsConnectorPackage__/ms_connector.war nach in das Applikationsverzeichnis ihres Applikationsservers +4. Mit der Version 1.2.0 wurde die Konfiguration eine eine Minimalkonfiguration [`default_config.properties`](./../config/default_config.properties) und eine in den MS-Connectorintegrierte Defaultkonfiguration aufgteilt. Die nachfolgende Aufzählung umfasst die neuen oder geänderten Konfigurationsparameter, beschreibt jedoch keine Aufteilung einer bestehenden Konfiguration in Minimal- und Defaultteil. Eine vollständige Beschreibung aller Konfigurationswerte finden Sie **hier**. +5. Update bestehender Dateien . Die nachfolgenden Dateien wurden geändert und erfordern eine Anpassung oder eine Übernahme dem Releasepacket, sofern die Anpassung nicht bereits durchgeführt wurde + + * __MsConnectorPackage__/config/templates/error_message.html +6. Erstellung neuer Dateien + - _KeyStore für ID Austria AuthBlock:_ Erstellen eines KeyStore mit mit öffentlichem und privaten Schlüssel welcher für die JWS Signature des technischen ID Austria AuthBlocks verwendet werden soll. +7. Neue Konfigurationsparameter + - *Allgemeine Konfiguration* + - ```eidas.ms.core.configRootDir``` + - *ID Austria Umsetzung* + - ```eidas.ms.auth.eIDAS.authblock.keystore.type``` + - ```eidas.ms.auth.eIDAS.authblock.keystore.path``` + - ```eidas.ms.auth.eIDAS.authblock.keystore.password``` + - ```eidas.ms.auth.eIDAS.authblock.key.alias``` + - ```eidas.ms.auth.eIDAS.authblock.key.password``` + - *Service-Provider Konfiguration Konfiguration* + - ```eidas.ms.sp.x.newEidMode``` +8. Gelöschte Konfigurationsparameter + + - ```authhandler.modules.bindingservice.bpk.target``` +9. Neue optionale Konfigurationsparameter + - *Allgemeine Konfiguration* + - ```eidas.ms.core.logging.level.info.errorcodes``` + - *eIDAS Node Kommunikation* + * ```eidas.ms.auth.eIDAS.node_v2.requesterId.useHashedForm``` + * ```eidas.ms.auth.eIDAS.node_v2.requesterId.lu.useStaticRequesterForAll``` + * ```eidas.ms.auth.eIDAS.node_v2.requesterId.useHashedForm``` + * ```eidas.ms.auth.eIDAS.node_v2.requesterId.useHashedForm``` + - *ID Austria Umsetzung* + - ```eidas.ms.auth.eIDAS.szrclient.eidasbind.mds.inject``` |