diff options
author | Thomas <> | 2023-06-01 16:36:34 +0200 |
---|---|---|
committer | Thomas <> | 2023-06-05 16:56:56 +0200 |
commit | 8842e4ff602c5c7766c509d1c895b8e7e67fb732 (patch) | |
tree | d4c1a796fcc79504a93895c429d28653bcefe8fd /modules | |
parent | a760feffb1bd8ba49e482546f273ef16307d44d7 (diff) | |
download | National_eIDAS_Gateway-8842e4ff602c5c7766c509d1c895b8e7e67fb732.tar.gz National_eIDAS_Gateway-8842e4ff602c5c7766c509d1c895b8e7e67fb732.tar.bz2 National_eIDAS_Gateway-8842e4ff602c5c7766c509d1c895b8e7e67fb732.zip |
fix(proxyservice): use requested SubjectNameIdFormat in eIDAS SAML2 response
Diffstat (limited to 'modules')
2 files changed, 194 insertions, 15 deletions
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java index d3c93421..8fc54e39 100644 --- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java +++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java @@ -92,15 +92,17 @@ public class ProxyServiceAuthenticationAction implements IAction { .statusCode(EidasConstants.SUCCESS_URI) .build()); - // TODO: check if we can use transient subjectNameIds - lightRespBuilder.subject(UUID.randomUUID().toString()); - lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT); + // build eIDAS attribute result + ImmutableAttributeMap eidasAttributes = buildAttributesFromAuthData(authData, eidasReq); + + injectSubjectNameId(lightRespBuilder, eidasAttributes, eidasReq); // TODO: lightRespBuilder.issuer(basicConfig.getBasicConfiguration( MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID)); lightRespBuilder.levelOfAssurance(authData.getEidasQaaLevel()); - lightRespBuilder.attributes(buildAttributesFromAuthData(authData, eidasReq)); + + lightRespBuilder.attributes(eidasAttributes); // set SLO response object of EAAF framework final SloInformationImpl sloInformation = new SloInformationImpl(); @@ -126,6 +128,7 @@ public class ProxyServiceAuthenticationAction implements IAction { } } + @Override public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { return true; @@ -422,4 +425,32 @@ public class ProxyServiceAuthenticationAction implements IAction { } } + private void injectSubjectNameId(Builder lightRespBuilder, ImmutableAttributeMap eidasAttributes, + ILightRequest eidasReq) { + if (NameIDType.PERSISTENT.equals(eidasReq.getNameIdFormat())) { + lightRespBuilder.subjectNameIdFormat(NameIDType.PERSISTENT); + final AttributeDefinition<?> attrDefPersonalId = + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + final AttributeDefinition<?> attrDefJurPersonalId = + attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first(); + + // set SubjectNameId as same as PersonalIdentifier + String subjectNameId = (String) eidasAttributes.getFirstValue(attrDefPersonalId); + if (subjectNameId != null) { + lightRespBuilder.subject(subjectNameId); + + } else { + lightRespBuilder.subject((String) eidasAttributes.getFirstValue(attrDefJurPersonalId)); + + } + + } else { + lightRespBuilder.subject(UUID.randomUUID().toString()); + lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT); + + } + } + } diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java index 50ce4033..333a823e 100644 --- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java +++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/ProxyServiceAuthenticationActionTest.java @@ -166,6 +166,36 @@ public class ProxyServiceAuthenticationActionTest { } @Test + public void responseWithoutMandatePersistentNameId() throws EaafException, SpecificCommunicationException { + Map<String, Object> attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, RandomStringUtils.randomAlphanumeric(10)); + IAuthData authData = generateDummyAuthData(attr, EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", + false); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.nameIdFormat(NameIDType.PERSISTENT); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + // perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + // validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME), NameIDType.PERSISTENT); + assertEquals("wrong attr. size", 4, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + authData.getDateOfBirth()); + + } + + @Test public void responseWithoutMandateAndOptionalAttributesExist() throws EaafException, SpecificCommunicationException { LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() @@ -287,6 +317,56 @@ public class ProxyServiceAuthenticationActionTest { } @Test + public void responseWithNatMandatePersistentNameId() throws EaafException, SpecificCommunicationException { + Map<String, Object> attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, + "1985-11-15"); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.nameIdFormat(NameIDType.PERSISTENT); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + IAuthData authData = generateDummyAuthData(attr, EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", + true); + + // perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + // validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME), NameIDType.PERSISTENT); + assertEquals("wrong attr. size", 8, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData + .getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData + .getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH, + (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME)); + + } + + @Test public void responseWithNatMandateButJurRequested() throws EaafException, SpecificCommunicationException { Map<String, Object> attr = new HashMap<>(); attr.put(PvpAttributeDefinitions.BPK_NAME, @@ -437,6 +517,63 @@ public class ProxyServiceAuthenticationActionTest { } @Test + public void responseWithJurMandatePersistentNameId() throws EaafException, SpecificCommunicationException { + Map<String, Object> attr = new HashMap<>(); + attr.put(PvpAttributeDefinitions.BPK_NAME, + "AT+XX:" + RandomStringUtils.randomAlphanumeric(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, + RandomStringUtils.randomAlphabetic(10)); + attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, + RandomStringUtils.randomAlphabetic(10)); + + IAuthData authData = generateDummyAuthData(attr, EaafConstants.EIDAS_LOA_HIGH, + RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", + true); + + LightRequest.Builder eidasRequestBuilder = generateBasicLightRequest(); + eidasRequestBuilder.nameIdFormat(NameIDType.PERSISTENT); + eidasRequestBuilder.requestedAttributes(ImmutableAttributeMap.builder() + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName( + EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()) + .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(EidasConstants.eIDAS_ATTR_LEGALNAME) + .first()) + .build()); + pendingReq.setEidasRequest(eidasRequestBuilder.build()); + + // perform test + SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData); + + // validate state + Assert.assertNotNull("Result should be not null", result); + + ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME), NameIDType.PERSISTENT); + assertEquals("wrong attr. size", 6, respAttr.size()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.BPK_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData + .getFamilyName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData + .getGivenName()); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getDateOfBirth()); + + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME)); + checkAttrValue(respAttr, EidasConstants.eIDAS_ATTR_LEGALNAME, + (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME)); + + assertNull("find nat. person subject: personalId", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER)); + assertNull("find nat. person subject: familyName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME)); + assertNull("find nat. person subject: givenName", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME)); + assertNull("find nat. person subject: dateOfBirth", + getAttrValue(respAttr, EidasConstants.eIDAS_ATTR_DATEOFBIRTH)); + + } + + @Test public void borisModeResponseWithJurMandate() throws EaafException, SpecificCommunicationException { Map<String, Object> attr = new HashMap<>(); attr.put(PvpAttributeDefinitions.BPK_NAME, @@ -835,26 +972,37 @@ public class ProxyServiceAuthenticationActionTest { } private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData) throws SpecificCommunicationException { + return validateBasicEidasResponse(authData, null, NameIDType.TRANSIENT); + + } + + private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData, String subjectNameId, + String persistent) throws SpecificCommunicationException { assertNotNull("not redirct Header", httpResp.getHeader("Location")); - assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token=")); + assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith( + "http://eidas.proxy/endpoint?token=")); String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length()); - - ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token), - ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); - + + ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder + .decode(token), + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + assertNotNull("responseId", resp.getId()); assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId()); assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState()); assertEquals("LoA", authData.getEidasQaaLevel(), resp.getLevelOfAssurance()); - + assertNotNull("subjectNameId", resp.getSubject()); - assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat()); - - assertFalse("not attributes", resp.getAttributes().isEmpty()); + if (subjectNameId != null) { + assertEquals("subjectNameId", subjectNameId, resp.getSubject()); + } + assertEquals("subjectNameIdFormat", persistent, resp.getSubjectNameIdFormat()); + + assertFalse("not attributes", resp.getAttributes().isEmpty()); return resp.getAttributes(); - + } - + private Builder generateBasicLightRequest() { return LightRequest.builder() .id(UUID.randomUUID().toString()) |