diff options
77 files changed, 6157 insertions, 96 deletions
| diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java index 3a93c1b8..2e70893b 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java @@ -86,6 +86,9 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder        ((EidAuthenticationData)authData).setEidStatus(authProcessData.isTestIdentity()             ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY); +       +       +            } else {        throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "             + authData.getClass().getName()); diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties index e7437840..f6d9bb7e 100644 --- a/connector/src/main/resources/application.properties +++ b/connector/src/main/resources/application.properties @@ -8,6 +8,7 @@ server.servlet.contextPath=/ms_connector  app.build.artifactId=ms_connector +  #############################################################################  ## SpringBoot Admin client  spring.boot.admin.client.enabled=false @@ -16,9 +17,9 @@ spring.boot.admin.client.enabled=false  ## SpringBoot Actuator  management.endpoints.web.exposure.include=health,info -  ############################################################################# -## MS-speccific eIDAS-Connector configuration +## Common parts of MS-speccific eIDAS application configuration +  #eidas.ms.context.url.prefix=  eidas.ms.context.url.request.validation=false  #eidas.ms.configRootDir=file:/.../config/ @@ -48,6 +49,29 @@ eidas.ms.core.pendingrequestid.digist.algorithm=HmacSHA256  #eidas.ms.core.pendingrequestid.digist.secret=pendingReqIdSecret +## HTTP-client defaults +eidas.ms.client.http.connection.timeout.socket=15 +eidas.ms.client.http.connection.timeout.connection=15 +eidas.ms.client.http.connection.timeout.request=15 + + +## Common PVP2 S-Profile (SAML2) 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 + +##only for advanced config +eidas.ms.configuration.pvp.scheme.validation=true +eidas.ms.configuration.pvp.enable.entitycategories=false + + + +############################################################################# +## MS-speccific eIDAS-Connector configuration +  ## eIDAS Ref. Implementation connector ###  eidas.ms.auth.eIDAS.node_v2.entityId=ownSpecificConnector  eidas.ms.auth.eIDAS.eid.testidentity.default=false @@ -139,13 +163,6 @@ eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.5=LegalName,true  #eidas.ms.pvp2.key.signing.password=password  eidas.ms.pvp2.metadata.validity=24 -#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 -  ## Service Provider configuration  #eidas.ms.sp.0.uniqueID=https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata @@ -159,5 +176,37 @@ eidas.ms.pvp2.metadata.validity=24  ##only for advanced config  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 + + + +############################################################################# +## MS-speccific eIDAS-Proxy-Service configuration + +#### eIDAS ms-specific Proxy-Service configuration +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +#eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint= + + +## PVP2 S-Profile communication with ID Austria System  +# EntityId and optional metadata of ID Austria System +#eidas.ms.modules.idaustriaauth.idp.entityId= +#eidas.ms.modules.idaustriaauth.idp.metadataUrl= + +# SAML2 client configuration +eidas.ms.modules.idaustriaauth.keystore.type=jks +#eidas.ms.modules.idaustriaauth.keystore.name= +#eidas.ms.modules.idaustriaauth.keystore.path= +#eidas.ms.modules.idaustriaauth.keystore.password= +#eidas.ms.modules.idaustriaauth.metadata.sign.alias= +#eidas.ms.modules.idaustriaauth.metadata.sign.password= +#eidas.ms.modules.idaustriaauth.request.sign.alias= +#eidas.ms.modules.idaustriaauth.request.sign.password= +#eidas.ms.modules.idaustriaauth.response.encryption.alias= +#eidas.ms.modules.idaustriaauth.response.encryption.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= +#eidas.ms.modules.idaustriaauth.truststore.password= + diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java index 17ecb2ca..552c448e 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java @@ -32,6 +32,7 @@ import org.w3c.dom.Element;  import at.asitplus.eidas.specific.connector.builder.AuthenticationDataBuilder;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;  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; @@ -72,6 +73,7 @@ public class AuthenticationDataBuilderTest {    private TestRequestImpl pendingReq;    private DummySpConfiguration oaParam; +  private Map<String, String> spConfig;    private String eidasBind;    private String authBlock; @@ -92,7 +94,7 @@ public class AuthenticationDataBuilderTest {      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"); @@ -106,25 +108,89 @@ public class AuthenticationDataBuilderTest {      authBlock = RandomStringUtils.randomAlphanumeric(20);      eidasBind = RandomStringUtils.randomAlphanumeric(20);      pendingReq.getSessionData(AuthProcessDataWrapper.class) -        .setGenericDataToSession(Constants.SZR_AUTHBLOCK, authBlock); -    pendingReq.getSessionData(AuthProcessDataWrapper.class) -        .setGenericDataToSession(Constants.EIDAS_BIND, eidasBind); -    pendingReq.getSessionData(AuthProcessDataWrapper.class)          .setQaaLevel(EaafConstants.EIDAS_LOA_PREFIX + RandomStringUtils.randomAlphabetic(5));      pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(          PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, -        RandomStringUtils.randomAlphabetic(2)); +        RandomStringUtils.randomAlphabetic(2).toUpperCase());      LocaleContextHolder.resetLocaleContext();    }    @Test -  public void eidMode() throws EaafAuthenticationException { +  public void eidasProxyMode() throws EaafAuthenticationException, EaafStorageException {      // initialize state      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(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, 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); +     +     +     +    // execute test +    IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq); + +     +    // validate state +    Assert.assertNotNull("AuthData null", authData); +    Assert.assertNull("authBlock null", authData.getGenericData(Constants.SZR_AUTHBLOCK, String.class)); +    Assert.assertNull("eidasBind null", authData.getGenericData(Constants.EIDAS_BIND, String.class)); +         +    Assert.assertEquals("LoA",  pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .getGenericDataFromSession(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, String.class),  +        authData.getEidasQaaLevel()); +    Assert.assertEquals("CitizenCountry", cc, authData.getCiticenCountryCode()); +    Assert.assertEquals("familyName", familyName, authData.getFamilyName()); +    Assert.assertEquals("givenName", givenName, authData.getGivenName()); +    Assert.assertEquals("DateOfBirth", dateOfBirth, authData.getFormatedDateOfBirth()); +     +    Assert.assertEquals("bPK", pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .getGenericDataFromSession(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class),  +        authData.getGenericData(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class)); +     +    Assert.assertEquals("testIdentity flag",  +        isTestIdentity ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY,  +        ((EidAuthenticationData)authData).getEidStatus()); +     +     +  } +   +  @Test +  public void eidMode() throws EaafAuthenticationException, EaafStorageException { +    // initialize state +    boolean isTestIdentity = RandomUtils.nextBoolean();      pendingReq.getSessionData(EidAuthProcessDataWrapper.class).setTestIdentity(isTestIdentity); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(Constants.SZR_AUTHBLOCK, authBlock); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(Constants.EIDAS_BIND, eidasBind);      // execute      IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq); diff --git a/connector/src/test/resources/config/junit_config_1.properties b/connector/src/test/resources/config/junit_config_1.properties index f6b3e4c1..044e33a6 100644 --- a/connector/src/test/resources/config/junit_config_1.properties +++ b/connector/src/test/resources/config/junit_config_1.properties @@ -116,6 +116,36 @@ eidas.ms.sp.1.policy.allowed.requested.targets=test  eidas.ms.sp.1.policy.hasBaseIdTransferRestriction=true + +#### eIDAS ms-specific Proxy-Service configuration +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint + + +## 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=keys/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=keys/junit_test.jks +eidas.ms.modules.idaustriaauth.truststore.password=password + +  ##only for advanced config  eidas.ms.configuration.sp.disableRegistrationRequirement=  #eidas.ms.configuration.restrictions.baseID.spTransmission= diff --git a/connector/src/test/resources/config/junit_config_1_springboot.properties b/connector/src/test/resources/config/junit_config_1_springboot.properties index e63cda7b..991036fe 100644 --- a/connector/src/test/resources/config/junit_config_1_springboot.properties +++ b/connector/src/test/resources/config/junit_config_1_springboot.properties @@ -43,7 +43,6 @@ eidas.ms.auth.eIDAS.szrclient.debug.logfullmessages=true  eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution=false -  ## PVP2 S-Profile end-point configuration  eidas.ms.pvp2.keystore.type=jks  eidas.ms.pvp2.keystore.path=keys/junit.jks @@ -81,3 +80,34 @@ eidas.ms.sp.1.pvp2.metadata.url=http://junit.test/metadata  eidas.ms.sp.1.policy.allowed.requested.targets=test  eidas.ms.sp.1.policy.hasBaseIdTransferRestriction=true + + +#### eIDAS ms-specific Proxy-Service configuration +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint + + +## 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=keys/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=keys/junit_test.jks +eidas.ms.modules.idaustriaauth.truststore.password=password + + diff --git a/connector/src/test/resources/config/junit_config_2_springboot.properties b/connector/src/test/resources/config/junit_config_2_springboot.properties index ecb22dec..de887fe6 100644 --- a/connector/src/test/resources/config/junit_config_2_springboot.properties +++ b/connector/src/test/resources/config/junit_config_2_springboot.properties @@ -81,3 +81,33 @@ eidas.ms.sp.1.pvp2.metadata.url=http://junit.test/metadata  eidas.ms.sp.1.policy.allowed.requested.targets=test  eidas.ms.sp.1.policy.hasBaseIdTransferRestriction=true + + +#### eIDAS ms-specific Proxy-Service configuration +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint + + +## 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=keys/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=keys/junit_test.jks +eidas.ms.modules.idaustriaauth.truststore.password=password + diff --git a/connector/src/test/resources/config/junit_config_3.properties b/connector/src/test/resources/config/junit_config_3.properties index 8b2c63a8..b4de5aa9 100644 --- a/connector/src/test/resources/config/junit_config_3.properties +++ b/connector/src/test/resources/config/junit_config_3.properties @@ -109,6 +109,37 @@ eidas.ms.sp.0.newEidMode=true  #eidas.ms.sp.0.policy.hasBaseIdTransferRestriction=false + +#### eIDAS ms-specific Proxy-Service configuration +eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy +eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint + + +## 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=keys/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=keys/junit_test.jks +eidas.ms.modules.idaustriaauth.truststore.password=password + + +  ##only for advanced config  eidas.ms.configuration.sp.disableRegistrationRequirement=  eidas.ms.configuration.restrictions.baseID.spTransmission= diff --git a/connector/src/test/resources/config/keys/junit_test.jks b/connector/src/test/resources/config/keys/junit_test.jksBinary files differ new file mode 100644 index 00000000..ee6254a9 --- /dev/null +++ b/connector/src/test/resources/config/keys/junit_test.jks 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 c8da9a4e..e2200ed1 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 @@ -48,8 +48,9 @@ public class Constants {    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 = diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java index 9900fa98..d1e69e84 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java @@ -143,7 +143,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {        }        // select forward URL regarding the selected environment -      String forwardUrl = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL); +      String forwardUrl = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL);        if (StringUtils.isNotEmpty(environment)) {          forwardUrl = selectedForwardUrlForEnvironment(environment);        } @@ -151,8 +151,8 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {        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[] { -            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          });        } @@ -214,17 +214,17 @@ 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(Constants.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(Constants.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 +      return basicConfig.getBasicConfiguration(Constants.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 +      return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL            + "." + MsEidasNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT);      } 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 4edfe32d..624700f9 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 @@ -137,7 +137,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", Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL, ((EaafException) e            .getOriginalException()).getParams()[0]);      } @@ -162,7 +162,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", Constants.CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL + "." + stage, ((EaafException) e            .getOriginalException()).getParams()[0]);      } diff --git a/eidas_modules/authmodule_id-austria/checks/spotbugs-exclude.xml b/eidas_modules/authmodule_id-austria/checks/spotbugs-exclude.xml new file mode 100644 index 00000000..311c3a8e --- /dev/null +++ b/eidas_modules/authmodule_id-austria/checks/spotbugs-exclude.xml @@ -0,0 +1,19 @@ +<?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> +</FindBugsFilter> diff --git a/eidas_modules/authmodule_id-austria/pom.xml b/eidas_modules/authmodule_id-austria/pom.xml index 25cbfc2e..3aabb069 100644 --- a/eidas_modules/authmodule_id-austria/pom.xml +++ b/eidas_modules/authmodule_id-austria/pom.xml @@ -79,7 +79,6 @@        <artifactId>mockwebserver</artifactId>        <scope>test</scope>      </dependency>   -      <dependency>        <groupId>at.asitplus.eidas.ms_specific</groupId>        <artifactId>connector_lib</artifactId> @@ -130,9 +129,9 @@          <groupId>com.github.spotbugs</groupId>          <artifactId>spotbugs-maven-plugin</artifactId>          <version>${spotbugs-maven-plugin.version}</version> -        <!-- configuration> +        <configuration>            <excludeFilterFile>checks/spotbugs-exclude.xml</excludeFilterFile> -        </configuration--> +        </configuration>        </plugin>        <plugin> diff --git a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java new file mode 100644 index 00000000..18eaee4b --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java @@ -0,0 +1,111 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +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"; + +  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)); +           +        } +      }); + +  public static final List<String> DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES = +      Collections.unmodifiableList(new ArrayList<String>() { +        private static final long serialVersionUID = 1L; +        { +          for (final Triple<String, String, Boolean> el : DEFAULT_REQUIRED_PVP_ATTRIBUTES) { +            if (el.getThird()) { +              add(el.getFirst()); +               +            } +          } +        } +      }); +} diff --git a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/builder/attributes/EidasConnecorUniqueIdAttributeBuilder.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMessageSource.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthMetadataConfiguration.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/config/IdAustriaAuthRequestBuilderConfiguration.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthMetadataController.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/controller/IdAustriaAuthSignalController.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java new file mode 100644 index 00000000..5dc04800 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java @@ -0,0 +1,377 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.tasks; + +import java.io.IOException; +import java.util.List; +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.msproxyservice.MsProxyServiceConstants; +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 = authConfig.getBasicConfiguration( +            IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID); +        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 List<String> requiredEidasNodeAttributes = +        IdAustriaAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES; +    try { +      // check if all attributes are include +      if (!extractor.containsAllRequiredAttributes() +          || !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()); + +      // TODO: add mandates if SEMPER are integrated + +    } catch (final EaafException | IOException e) { +      throw new EaafBuilderException(ERROR_PVP_06, null, e.getMessage(), e); + +    } +  } + +  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); +    if (PvpAttributeDefinitions.BPK_NAME.equals(attrName)) { +      log.trace("Find bPK attribute. Extract eIDAS identifier ... "); +      session.setGenericDataToSession(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, +          extractBpkFromResponse(attrValue)); + +    } else { +      session.setGenericDataToSession(attrName, attrValue); + +    } + +  } + +  private String extractBpkFromResponse(String pvpBpkAttrValue) { +    final String[] split = pvpBpkAttrValue.split(":", 2); +    if (split.length == 2) { +      return split[1]; + +    } else { +      log.warn("PVP bPK attribute: {} has wrong format. Use it as it is.", pvpBpkAttrValue); +      return pvpBpkAttrValue; + +    } +  } + +  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().getMessage() }); + +    } + +  } + +  /** +   * 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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java new file mode 100644 index 00000000..fc46ac8b --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java @@ -0,0 +1,209 @@ +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.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.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.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 = authConfig.getBasicConfiguration( +          IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID); +      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 +    final Attribute attrEidasConnectorId = PvpAttributeBuilder.buildEmptyAttribute( +        ExtendedPvpAttributeDefinitions.EIDAS_CONNECTOR_UNIQUEID_NAME); +    final EaafRequestedAttribute attrEidasConnectorIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +        attrEidasConnectorId, +        true, +        pendingReq.getServiceProviderConfiguration().getUniqueIdentifier()); +    attributs.add(attrEidasConnectorIdReqAttr);     +     +     +    // build EID sector for identification attribute +    final Attribute attr = PvpAttributeBuilder.buildEmptyAttribute( +        PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME); +    final EaafRequestedAttribute bpkTargetReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +        attr, +        true, +        pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); +    attributs.add(bpkTargetReqAttr); + + +    // set requested LoA as attribute  +    final Attribute loaAttr = PvpAttributeBuilder.buildEmptyAttribute( +        PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME); +    final EaafRequestedAttribute loaReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +        loaAttr, +        true, +        selectHighestLoa(pendingReq.getServiceProviderConfiguration().getRequiredLoA())); +    attributs.add(loaReqAttr); +     +     +    //set ProviderName if available +    String providerName = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getProviderName(); +    if (StringUtils.isNotEmpty(providerName)) { +      final Attribute providerNameAttr = PvpAttributeBuilder.buildEmptyAttribute( +          ExtendedPvpAttributeDefinitions.SP_FRIENDLYNAME_NAME); +      final EaafRequestedAttribute providerNameReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +          providerNameAttr, +          true, +          providerName); +      attributs.add(providerNameReqAttr); +             +    } +     +     +    //set ProviderName if available +    String requesterId = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getRequesterId(); +    if (StringUtils.isNotEmpty(requesterId)) { +      final Attribute requesterIdAttr = PvpAttributeBuilder.buildEmptyAttribute( +          ExtendedPvpAttributeDefinitions.SP_UNIQUEID_NAME); +      final EaafRequestedAttribute requesterIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +          requesterIdAttr, +          true, +          requesterId); +      attributs.add(requesterIdReqAttr); +             +    } + +    return attributs; +  } + +} diff --git a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthCredentialProvider.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/utils/IdAustriaAuthMetadataProvider.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder b/eidas_modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder new file mode 100644 index 00000000..65e9482c --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/main/resources/META-INF/services/at.gv.egiz.eaaf.core.api.idp.IAttributeBuilder @@ -0,0 +1 @@ +at.asitplus.eidas.specific.modules.auth.idaustria.builder.attributes.EidasConnecorUniqueIdAttributeBuilder diff --git a/eidas_modules/authmodule_id-austria/src/main/resources/messages/idaustria_auth_messages.properties b/eidas_modules/authmodule_id-austria/src/main/resources/messages/idaustria_auth_messages.properties new file mode 100644 index 00000000..6de6e0dc --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml b/eidas_modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml index e46b3c15..ebd5c54d 100644 --- a/eidas_modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml +++ b/eidas_modules/authmodule_id-austria/src/main/resources/process/id_austria.Authentication.process.xml @@ -2,19 +2,17 @@  <pd:ProcessDefinition id="idAustriaForEidasProxyService"    xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1"> - - -  <pd:Task id="finalizeAuthentication"  class="FinalizeAuthenticationTask" /> - +  <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:Transition  from="start"  to="finalizeAuthentication" /> -   -  <!-- TODO: add ID Austria communication steps --> - -  <pd:Transition  from="finalizeAuthentication" to="end" /> -   -  <pd:EndEvent id="end" /> +  <pd:EndEvent  id="end" />  </pd:ProcessDefinition> diff --git a/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml b/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml index adb54dc8..d2d16bf9 100644 --- a/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml +++ b/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_auth.beans.xml @@ -14,4 +14,23 @@    <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/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml b/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml index f95d71cc..9da9145d 100644 --- a/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml +++ b/eidas_modules/authmodule_id-austria/src/main/resources/spring/id_austria_task.beans.xml @@ -11,5 +11,13 @@    <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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/builder/attributes/EidasConnecorUniqueIdAttributeBuilderTest.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/config/IdAustriaAuthMessageSourceTest.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java new file mode 100644 index 00000000..ef0c4da0 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java @@ -0,0 +1,183 @@ +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.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.connector.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(7); + +  } + +  @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(8); + +  } + +  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()); + +    //check XML scheme +    final SchemaValidationFilter schemaFilter = new SchemaValidationFilter(); +    schemaFilter.filter(metadata); + +    //check signature +    final SimpleMetadataSignatureVerificationFilter sigFilter = +        new SimpleMetadataSignatureVerificationFilter(credProvider.getKeyStore().getFirst(), +            metadata.getEntityID()); +    sigFilter.filter(metadata); + +    //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).getFormat()); + +    Assert.assertFalse("AttributeConsumingServices", +        spSsoDesc.getAttributeConsumingServices().isEmpty()); +    Assert.assertEquals("#RequestAttributes", numberOfRequestedAttributes, +        spSsoDesc.getAttributeConsumingServices().get(0).getRequestAttributes().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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthSignalControllerTest.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java new file mode 100644 index 00000000..a0446ad9 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java @@ -0,0 +1,690 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.task; + +import static org.junit.Assert.assertThrows; + +import java.io.IOException; +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.joda.time.DateTime; +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.connector.config.ServiceProviderConfiguration; +import at.asitplus.eidas.specific.connector.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.MsProxyServiceConstants; +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()); +     +    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,MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, "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,MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, "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,MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, "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,MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, "QVGm48cqcasfasfsafsafdM4UcyhDTNGYmVdrIoY="); +         +  } +   +  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(DateTime.now()); +    final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class); +    issuer.setValue(idpEntityId); +    response.setIssuer(issuer); + +    if (validConditions) { +      response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5)); + +    } + +    return Saml2Utils.signSamlObject(response, credential, true); +  } +} diff --git a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java new file mode 100644 index 00000000..e5493332 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java @@ -0,0 +1,380 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.task; + +import static org.junit.Assert.assertThrows; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashMap; +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.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.connector.config.ServiceProviderConfiguration; +import at.asitplus.eidas.specific.connector.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.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.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 at.gv.egiz.eaaf.modules.pvp2.test.binding.PostBindingTest; +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", 3, 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()); +     +  } + +  @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); +     +    //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.ServiceProviderFriendlyName", +        reqAttr.getAttributes().get(3).getName()); +    Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(1).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"); +    Assert.assertEquals("Req. Attr. Value", eidasReq.getProviderName(), +        ((XSString)reqAttr.getAttributes().get(3).getAttributeValues().get(0)).getValue()); +     +    Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderUniqueId", +        reqAttr.getAttributes().get(4).getName()); +    Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(1).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.getRequesterId(), +        ((XSString)reqAttr.getAttributes().get(4).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 PostBindingTest.class.getResourceAsStream("/data/pvp_postbinding_template.html"); +      } + +      @Override +      public String getClasspathTemplateDir() { +        return null; + +      } +    }; +  } +} diff --git a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthCredentialProviderTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthCredentialProviderTest.java new file mode 100644 index 00000000..99a00089 --- /dev/null +++ b/eidas_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.connector.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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java new file mode 100644 index 00000000..fa0d95a6 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderFirstTest.java @@ -0,0 +1,235 @@ +package at.asitplus.eidas.specific.modules.auth.idaustria.test.utils; + +import java.io.IOException; + +import org.apache.commons.lang3.RandomStringUtils; +import org.joda.time.DateTime; +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.connector.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(DateTime.now().plusDays(1)); +    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/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/utils/IdAustriaAuthMetadataProviderSecondTest.java b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/config/junit.jks b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit.jksBinary files differ new file mode 100644 index 00000000..59e6ad13 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit.jks diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties index e69de29b..66c13dbc 100644 --- a/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_config_1.properties +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_test.jks b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_test.jksBinary files differ new file mode 100644 index 00000000..ee6254a9 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_test.jks diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jks b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jksBinary files differ new file mode 100644 index 00000000..8fe3b03c --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/resources/config/junit_test_no_trust_certs.jks diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/config/pvp.jks b/eidas_modules/authmodule_id-austria/src/test/resources/config/pvp.jksBinary files differ new file mode 100644 index 00000000..f0a5a09a --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/resources/config/pvp.jks diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/config/pvp.p12 b/eidas_modules/authmodule_id-austria/src/test/resources/config/pvp.p12Binary files differ new file mode 100644 index 00000000..183342f7 --- /dev/null +++ b/eidas_modules/authmodule_id-austria/src/test/resources/config/pvp.p12 diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID.xml new file mode 100644 index 00000000..8d3c1c66 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_bpk_without_prefix.xml b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_minimum.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_minimum.xml new file mode 100644 index 00000000..be8e7cc3 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_eid_sector_attr.xml b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_wrong_data.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_wrong_data.xml new file mode 100644 index 00000000..cc534d09 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_wrong_destination_endpoint.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_wrong_destination_endpoint.xml new file mode 100644 index 00000000..2ae05ca1 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_classpath_entityid.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_classpath_entityid.xml new file mode 100644 index 00000000..0fd675e2 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error.xml new file mode 100644 index 00000000..ee5920dc --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_empty_subcode.xml b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_userstop.xml b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_without_sig_with_error_without_subcode.xml b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/eidas_node_siging.crt b/eidas_modules/authmodule_id-austria/src/test/resources/data/eidas_node_siging.crt new file mode 100644 index 00000000..95843ea9 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_classpath_entity.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_classpath_entity.xml new file mode 100644 index 00000000..de565887 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig.xml new file mode 100644 index 00000000..bc55fe62 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig2.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_no_sig2.xml new file mode 100644 index 00000000..bdc176a0 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_notvalid.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_notvalid.xml new file mode 100644 index 00000000..86665a9c --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/idp_metadata_sig_valid_wrong_alg.xml b/eidas_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/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/junit_keystore_metadata.crt b/eidas_modules/authmodule_id-austria/src/test/resources/data/junit_keystore_metadata.crt new file mode 100644 index 00000000..35831d03 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/junit_keystore_signing.crt b/eidas_modules/authmodule_id-austria/src/test/resources/data/junit_keystore_signing.crt new file mode 100644 index 00000000..35a82125 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/moa_sig_signing.crt b/eidas_modules/authmodule_id-austria/src/test/resources/data/moa_sig_signing.crt new file mode 100644 index 00000000..fda99f2b --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/pvp_postbinding_template.html b/eidas_modules/authmodule_id-austria/src/test/resources/data/pvp_postbinding_template.html new file mode 100644 index 00000000..5c65e25a --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/data/sp_metadata_junit.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/sp_metadata_junit.xml new file mode 100644 index 00000000..32e90604 --- /dev/null +++ b/eidas_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/eidas_modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml b/eidas_modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml index 0f42ceb5..16959dc5 100644 --- a/eidas_modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml +++ b/eidas_modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_basic_test.xml @@ -11,8 +11,18 @@    <import resource="classpath:/SpringTest-context_authManager.xml" /> -  <import resource="classpath:/spring/id_austria_auth.beans.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" />  </beans>
\ No newline at end of file diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_lazy.xml b/eidas_modules/authmodule_id-austria/src/test/resources/spring/SpringTest-context_lazy.xml new file mode 100644 index 00000000..5360960b --- /dev/null +++ b/eidas_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/eidas_modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml b/eidas_modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml index 53ca4d4d..cdc9fa95 100644 --- a/eidas_modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml +++ b/eidas_modules/eidas_proxy-sevice/checks/spotbugs-exclude.xml @@ -9,4 +9,12 @@          <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>      </FindBugsFilter> diff --git a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java index a7c3b8e2..e5d4d33e 100644 --- a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java +++ b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java @@ -1,5 +1,9 @@  package at.asitplus.eidas.specific.modules.msproxyservice; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder; +  /**   * Constants for MS-specific eIDAS Proxy-Service.   *  @@ -11,7 +15,15 @@ public class MsProxyServiceConstants {    //general constants    public static final String TEMPLATE_SP_UNIQUE_ID = "eidasProxyAuth_from_{0}_type_{1}"; +  public static final String ATTR_EIDAS_PERSONAL_IDENTIFIER =  +      AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER + PvpAttributeDefinitions.BPK_NAME; +      //configuration constants +  public static final String CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID = Constants.CONIG_PROPS_EIDAS_NODE +      + ".proxy.entityId"; +  public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = Constants.CONIG_PROPS_EIDAS_NODE +      + ".proxy.forward.endpoint"; +    //http end-points    public static final String EIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/light/idp/post"; diff --git a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java index 47cfd3a9..aafe57e7 100644 --- a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java +++ b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java @@ -149,6 +149,32 @@ public class EidasProxyServiceController extends AbstractController implements I    } +  @Override +  public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, +      IRequest protocolRequest) throws Throwable { +     +    //TODO: implement error handling for eIDAS Node communication     +    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; +     +  }    /**     * Validate incoming eIDAS request. @@ -180,9 +206,12 @@ public class EidasProxyServiceController extends AbstractController implements I      try {        String spCountry = eidasRequest.getSpCountryCode();                          Map<String, String> spConfigMap = new HashMap<>(); + +      //TODO: how we get the EntityId from eIDAS connector?        spConfigMap.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER,            MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID,                 spCountry, eidasRequest.getSpType())); +              ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(spConfigMap, authConfig);        final String ccCountry = authConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, @@ -198,35 +227,7 @@ public class EidasProxyServiceController extends AbstractController implements I      } catch (EaafException e) {        throw new EidasProxyServiceException(ERROR_04, new Object[] {e.getMessage()}, e); -    } -     -  } - -  @Override -  public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, -      IRequest protocolRequest) throws Throwable { -     -    //TODO: implement error handling for eIDAS Node communication     -    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; -     +    }        }  } diff --git a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java index 3ff35ac9..c51db460 100644 --- a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java +++ b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -1,18 +1,53 @@  package at.asitplus.eidas.specific.modules.msproxyservice.protocol; +import java.io.IOException; +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.connector.gui.StaticGuiBuilderConfiguration; +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.msproxyservice.MsProxyServiceConstants; +import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;  import at.gv.egiz.eaaf.core.api.IRequest; +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.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   *   */ @@ -20,33 +55,178 @@ import lombok.extern.slf4j.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 +  EidasAttributeRegistry attrRegistry; +    @Override    public SloInformationInterface processRequest(IRequest pendingReq, HttpServletRequest httpReq,        HttpServletResponse httpResp, IAuthData authData) throws EaafException {      if (pendingReq instanceof ProxyServicePendingRequest) { +      try {         +        ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest(); +         +        //build eIDAS response +        Builder lightRespBuilder = LightResponse.builder(); +        lightRespBuilder.id(UUID.randomUUID().toString()); +        lightRespBuilder.inResponseToId(eidasReq.getId()); +        lightRespBuilder.relayState(eidasReq.getRelayState()); +         +        lightRespBuilder.status(ResponseStatus.builder() +            .statusCode(Constants.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)); +         +        // put request into shared cache +        final BinaryLightToken token = putResponseInCommunicationCache(lightRespBuilder.build()); +        final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token); + +        // 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, tokenBase64); + +        return sloInformation; + +      } catch (ServletException | IOException | GuiBuildException e) { +        throw new EidasProxyServiceException("eidas.proxyservice.06", null, e); + +      } -       -      return null; -            } 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) {     +  public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {      return true; -     +    }    @Override    public String getDefaultActionName() {      return PROXYSERVICE_AUTH_ACTION_NAME; + +  } +   +   +  @PostConstruct  +  private void checkConfiguration() { +    //TODO: validate configuration on start-up    } +   +   +  private ImmutableAttributeMap buildAttributesFromAuthData(IAuthData authData) { +    final AttributeDefinition<?> attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( +        Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); +    final AttributeDefinition<?> attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( +        Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first(); +    final AttributeDefinition<?> attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( +        Constants.eIDAS_ATTR_CURRENTGIVENNAME).first(); +    final AttributeDefinition<?> attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName( +        Constants.eIDAS_ATTR_DATEOFBIRTH).first(); +    +    final ImmutableAttributeMap.Builder attributeMap =  +        ImmutableAttributeMap.builder().put(attrDefPersonalId,  +            authData.getGenericData(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class)) +        .put(attrDefFamilyName, authData.getFamilyName()) +        .put(attrDefGivenName, authData.getGivenName()) +        .put(attrDefDateOfBirth, authData.getFormatedDateOfBirth()); +     +    return attributeMap.build(); +     +  } +   +  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; +  } + +  private void forwardToEidasProxy(IRequest pendingReq, HttpServletRequest httpReq, +      HttpServletResponse httpResp, String tokenBase64) throws EaafConfigurationException, IOException, +      GuiBuildException { +    // 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( +        Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, +        Constants.FORWARD_METHOD_GET).equals(Constants.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, +          Constants.TEMPLATE_POST_FORWARD_NAME, +          null, +          resourceLoader); + +      config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl); +      config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME, +          EidasParameterKeys.TOKEN.toString()); +      config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, +          tokenBase64); + +      guiBuilder.build(httpReq, httpResp, config, "Forward to eIDASNode form"); + +    } + +  }  } diff --git a/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties b/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties index 0437554b..5c4c51b9 100644 --- a/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties +++ b/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties @@ -3,5 +3,6 @@ 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 Service-Provider country-code in Authn. request. Authentication not possible +eidas.proxyservice.06=Can not build eIDAS Proxy-Service response. Authentication FAILED.  eidas.proxyservice.99=Internal error during eIDAS Proxy-Service authentication
\ No newline at end of file diff --git a/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java b/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java index eb5280b3..96429d71 100644 --- a/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -5,10 +5,13 @@ import static org.junit.Assert.assertThrows;  import java.net.URISyntaxException;  import java.util.Arrays; +import java.util.Collections;  import java.util.Date;  import java.util.HashMap;  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.Test; @@ -26,6 +29,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;  import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap;  import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummySpConfiguration;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask; +import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;  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; @@ -35,6 +39,7 @@ 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.light.impl.LightRequest;  @RunWith(SpringJUnit4ClassRunner.class)  @PrepareForTest(CreateIdentityLinkTask.class) @@ -65,6 +70,9 @@ public class ProxyServiceAuthenticationActionTest {      RequestContextHolder.resetRequestAttributes();      RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); +    basicConfig.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint",  +        "http://eidas.proxy/endpoint"); +          final Map<String, String> spConfig = new HashMap<>();      spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp");      spConfig.put("target", "urn:publicid:gv.at:cdid+XX"); @@ -76,6 +84,17 @@ public class ProxyServiceAuthenticationActionTest {      pendingReq.initialize(httpReq, basicConfig);      pendingReq.setOnlineApplicationConfiguration(oaParam); +    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()); +        }    @Test @@ -88,16 +107,35 @@ public class ProxyServiceAuthenticationActionTest {      Assert.assertEquals("wrong errorCode", "eidas.proxyservice.99", exception.getErrorId());    } + +  @Test +  public void missingForwardUrl() {         +    Map<String, Object> attr = new HashMap<>(); +    attr.put(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,  +        "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));     +    IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, +        RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18"); +    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 dummyResponseActionTest() throws EaafException { -    IAuthData authData = generateDummyAuthData(); +    Map<String, Object> attr = new HashMap<>(); +    attr.put(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,  +        "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));     +    IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH, +        RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18");      //perform test      SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);      //validate state -    Assert.assertNull("Result should be not null", result); +    Assert.assertNotNull("Result should be not null", result);    } @@ -112,6 +150,12 @@ public class ProxyServiceAuthenticationActionTest {    }    private IAuthData generateDummyAuthData() { +    return generateDummyAuthData(Collections.emptyMap(), EaafConstants.EIDAS_LOA_LOW,  +        RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01"); +     +  } +   +  private IAuthData generateDummyAuthData(Map<String, Object> attrs, String loa, String familyName, String givenName, String dateOfBirth) {      return new IAuthData() {        @Override @@ -176,26 +220,28 @@ public class ProxyServiceAuthenticationActionTest {        @Override        public String getGivenName() { -        // TODO Auto-generated method stub -        return null; +        return givenName;        }        @Override        public <T> T getGenericData(String key, Class<T> clazz) { -        // TODO Auto-generated method stub -        return null; +        if (attrs.containsKey(key)) { +          return (T) attrs.get(key); +           +        } else { +          return null;   +        } +                }        @Override        public String getFormatedDateOfBirth() { -        // TODO Auto-generated method stub -        return null; +        return dateOfBirth;        }        @Override        public String getFamilyName() { -        // TODO Auto-generated method stub -        return null; +        return familyName;        }        @Override @@ -212,8 +258,8 @@ public class ProxyServiceAuthenticationActionTest {        @Override        public String getEidasQaaLevel() { -        // TODO Auto-generated method stub -        return null; +        return loa; +                }        @Override diff --git a/eidas_modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties b/eidas_modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties index b03e2c81..4f3b82b5 100644 --- a/eidas_modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties +++ b/eidas_modules/eidas_proxy-sevice/src/test/resources/config/junit_config_1.properties @@ -1,3 +1,6 @@  ## Basic service configuration  eidas.ms.context.url.prefix=http://localhost -eidas.ms.context.url.request.validation=false
\ No newline at end of file +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
\ No newline at end of file diff --git a/eidas_modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml b/eidas_modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml index 6a1505f4..2c16d796 100644 --- a/eidas_modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml +++ b/eidas_modules/eidas_proxy-sevice/src/test/resources/spring/SpringTest-context_basic_test.xml @@ -16,6 +16,9 @@    <bean id="springManagedSpecificProxyserviceCommunicationService"          class="at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService" /> + <bean id="mvcGUIBuilderImpl" +    class="at.asitplus.eidas.specific.connector.gui.SpringMvcGuiFormBuilderImpl" /> +    <bean id="specificConnectorAttributesFileWithPath"      class="java.lang.String">      <constructor-arg @@ -477,9 +477,24 @@        </dependency>        <dependency>          <groupId>at.gv.egiz.eaaf</groupId> +        <artifactId>eaaf_module_pvp2_core</artifactId> +        <version>${eaaf-core.version}</version> +        <scope>test</scope> +        <type>test-jar</type> +      </dependency>  +      <dependency> +        <groupId>at.gv.egiz.eaaf</groupId> +        <artifactId>eaaf_module_pvp2_idp</artifactId> +        <version>${eaaf-core.version}</version> +        <scope>test</scope> +        <type>test-jar</type> +      </dependency> +      <dependency> +        <groupId>at.gv.egiz.eaaf</groupId>          <artifactId>eaaf_module_pvp2_sp</artifactId>          <version>${eaaf-core.version}</version>          <scope>test</scope> +        <type>test-jar</type>        </dependency>        <dependency>          <groupId>at.gv.egiz.eaaf</groupId> | 
