aboutsummaryrefslogtreecommitdiff
path: root/ms_specific_connector
diff options
context:
space:
mode:
authorThomas <>2022-12-19 15:50:38 +0100
committerThomas <>2022-12-19 15:50:38 +0100
commitd2dec4601c41131c3ca509a8f7907b91af0ba2a6 (patch)
tree999634c3edaf5d45774593b4cdece1dada857dab /ms_specific_connector
parentc2fa7fa970f717b8b4e27098b3d2b9341c59fae1 (diff)
downloadNational_eIDAS_Gateway-d2dec4601c41131c3ca509a8f7907b91af0ba2a6.tar.gz
National_eIDAS_Gateway-d2dec4601c41131c3ca509a8f7907b91af0ba2a6.tar.bz2
National_eIDAS_Gateway-d2dec4601c41131c3ca509a8f7907b91af0ba2a6.zip
feat(eidas-connector): support not-notified LoA
- not-notified LoA is currently used by Ukraine
Diffstat (limited to 'ms_specific_connector')
-rw-r--r--ms_specific_connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java14
-rw-r--r--ms_specific_connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java151
-rw-r--r--ms_specific_connector/src/test/resources/config/junit_config_1_springboot.properties1
3 files changed, 152 insertions, 14 deletions
diff --git a/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
index 23702264..0452353a 100644
--- a/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
+++ b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
@@ -58,7 +58,7 @@ import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestPostProcessor;
import at.gv.egiz.eaaf.modules.pvp2.exception.NameIdFormatNotSupportedException;
-import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance;
+import eu.eidas.auth.commons.protocol.eidas.NotifiedLevelOfAssurance;
public class AuthnRequestValidator implements IAuthnRequestPostProcessor {
@@ -266,13 +266,13 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {
final List<String> reqLoA = extractLoA(authnReq);
log.trace("SP requests LoA with: {}", String.join(", ", reqLoA));
- LevelOfAssurance minimumLoAFromConfig = LevelOfAssurance.fromString(basicConfig.getBasicConfiguration(
- MsEidasNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL,
- EaafConstants.EIDAS_LOA_HIGH));
+ NotifiedLevelOfAssurance minimumLoAFromConfig = NotifiedLevelOfAssurance.fromString(
+ basicConfig.getBasicConfiguration(MsEidasNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL,
+ EaafConstants.EIDAS_LOA_HIGH));
if (minimumLoAFromConfig == null) {
log.warn("Can not load minimum LoA from configuration. Use LoA: {} as default",
EaafConstants.EIDAS_LOA_HIGH);
- minimumLoAFromConfig = LevelOfAssurance.HIGH;
+ minimumLoAFromConfig = NotifiedLevelOfAssurance.HIGH;
}
@@ -281,7 +281,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {
final List<String> allowedLoA = new ArrayList<>();
for (final String loa : reqLoA) {
try {
- final LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa);
+ final NotifiedLevelOfAssurance intLoa = NotifiedLevelOfAssurance.fromString(loa);
String selectedLoA = EaafConstants.EIDAS_LOA_HIGH;
if (intLoa != null
&& intLoa.numericValue() <= minimumLoAFromConfig.numericValue()) {
@@ -340,11 +340,13 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {
} else {
result.add(authContext.getAuthnContextClassRefs().get(0).getAuthnContextClassRef());
+
}
} else if (authContext.getComparison().equals(AuthnContextComparisonTypeEnumeration.EXACT)) {
for (final AuthnContextClassRef el : authContext.getAuthnContextClassRefs()) {
result.add(el.getAuthnContextClassRef());
+
}
} else {
diff --git a/ms_specific_connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java b/ms_specific_connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java
index e5fea3b3..46079ac5 100644
--- a/ms_specific_connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java
+++ b/ms_specific_connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java
@@ -372,7 +372,7 @@ public class FullStartUpAndProcessTest {
Assert.assertFalse("eidas req. token", eidasNodeReqToken.isEmpty());
//check eIDAS node request and build respose
- String eidasRespToken = validateEidasNodeRequestAndBuildResponse(eidasNodeReqToken);
+ String eidasRespToken = validateEidasNodeRequestAndBuildResponse(eidasNodeReqToken, EaafConstants.EIDAS_LOA_HIGH);
Assert.assertFalse("eidas resp. token", eidasRespToken.isEmpty());
@@ -450,6 +450,142 @@ public class FullStartUpAndProcessTest {
}
+ @Test
+ public void fullSuccessProcessNonNotifiedLoa() throws EaafException, Exception {
+ //start authentication process by sending a SAML2 Authn-Request
+ MockHttpServletRequest saml2Req = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
+ injectSaml2AuthnReq(saml2Req);
+ MockHttpServletResponse selectCountryResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(saml2Req, selectCountryResp));
+
+ // send SAML2 AuthnRequest
+ sProfile.pvpIdpPostRequest(saml2Req, selectCountryResp);
+
+ //check country-selection response
+ Assert.assertEquals("no country-selection page", 200, selectCountryResp.getStatus());
+ Assert.assertEquals("cc-selection page", "text/html;charset=UTF-8", selectCountryResp.getContentType());
+ String selectionPage = selectCountryResp.getContentAsString();
+ Assert.assertNotNull("selectionPage is null", selectionPage);
+ Assert.assertFalse("selectionPage is empty", selectionPage.isEmpty());
+
+ String pendingReqId = extractRequestToken(selectionPage,
+ "<input type=\"hidden\" name=\"pendingid\" value=\"");
+ Assert.assertFalse("PendingReqId", pendingReqId.isEmpty());
+
+
+ //set UA as citizen country-code
+ cc = "UA";
+ pseudonym = RandomStringUtils.randomNumeric(64);
+ personalId = cc + "/AT/" + pseudonym;
+ familyName = RandomStringUtils.randomAlphabetic(10);
+ givenName = RandomStringUtils.randomAlphabetic(10);
+ dateOfBirth = "2015-10-12";
+
+
+ // set-up country-selection request
+ MockHttpServletRequest selectCountryReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
+ selectCountryReq.setParameter("pendingid", pendingReqId);
+ selectCountryReq.setParameter("selectedCountry", cc);
+
+ MockHttpServletResponse forwardEidasNodeResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(selectCountryReq, forwardEidasNodeResp));
+
+ // send country-selection request
+ signal.performGenericAuthenticationProcess(selectCountryReq, forwardEidasNodeResp);
+
+ //check forward to eIDAS node response
+ Assert.assertEquals("forward to eIDAS Node", 200, forwardEidasNodeResp.getStatus());
+ Assert.assertEquals("forward to eIDAS Node page", "text/html;charset=UTF-8", forwardEidasNodeResp.getContentType());
+ String forwardPage = forwardEidasNodeResp.getContentAsString();
+ Assert.assertNotNull("forward to eIDAS Node is null", forwardPage);
+ Assert.assertFalse("forward to eIDAS Node is empty", forwardPage.isEmpty());
+
+ String eidasNodeReqToken = extractRequestToken(forwardPage,
+ "<input type=\"hidden\" name=\"token\" value=\"");
+ Assert.assertFalse("eidas req. token", eidasNodeReqToken.isEmpty());
+
+ //check eIDAS node request and build respose
+ String eidasRespToken = validateEidasNodeRequestAndBuildResponse(eidasNodeReqToken,
+ EaafConstants.EIDAS_LOA_NOT_NOTIFIED_PREFIX + "high");
+ Assert.assertFalse("eidas resp. token", eidasRespToken.isEmpty());
+
+
+ // set-up eIDAS-node response
+ MockHttpServletRequest eidasNodeRespReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
+ eidasNodeRespReq.setParameter("token", eidasRespToken);
+
+ MockHttpServletResponse finalizeResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(eidasNodeRespReq, finalizeResp));
+
+ // inject ZMR, ERnP and SZR responses for matching
+ injectZmrResponse();
+ injectSzrResponse();
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody("{}") // empty response because we simulate result from ZMR
+ .setHeader("Content-Type", "application/json;charset=utf-8"));
+
+ //excute eIDAS node response
+ eidasSignal.restoreEidasAuthProcess(eidasNodeRespReq, finalizeResp);
+
+ //validate state
+ Assert.assertEquals("forward to finalization", 302, finalizeResp.getStatus());
+ Assert.assertNotNull("missing redirect header", finalizeResp.getHeader("Location"));
+ Assert.assertTrue("wrong redirect header", finalizeResp.getHeader("Location").startsWith(FINAL_REDIRECT));
+ String finalPendingReqId = finalizeResp.getHeader("Location").substring(FINAL_REDIRECT.length());
+ Assert.assertFalse("final pendingRequestId", finalPendingReqId.isEmpty());
+
+
+ //set-up finalization request
+ MockHttpServletRequest finalizationReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
+ finalizationReq.setParameter("pendingid", finalPendingReqId);
+
+ MockHttpServletResponse saml2Resp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(finalizationReq, saml2Resp));
+
+ // exexcute finalization step
+ finalize.finalizeAuthProtocol(finalizationReq, saml2Resp);
+
+ //validate state
+ Assert.assertEquals("forward to finalization", 200, saml2Resp.getStatus());
+ Assert.assertEquals("forward to eIDAS Node page", "text/html;charset=UTF-8", saml2Resp.getContentType());
+ String saml2RespPage = saml2Resp.getContentAsString();
+ Assert.assertNotNull("selectionPage is null", saml2RespPage);
+ Assert.assertFalse("selectionPage is empty", saml2RespPage.isEmpty());
+
+ //validate SAML2 response
+ String saml2RespB64 = extractRequestToken(saml2RespPage,
+ "<input type=\"hidden\" name=\"SAMLResponse\" value=\"");
+ Assert.assertNotNull("SAML2 response", saml2RespB64);
+
+ StatusResponseType saml2 = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ new ByteArrayInputStream(Base64Utils.decodeFromString(saml2RespB64)));
+ Assert.assertEquals("SAML2 status", EidasConstants.SUCCESS_URI, saml2.getStatus().getStatusCode().getValue());
+
+ final AssertionAttributeExtractor extractor = new AssertionAttributeExtractor(saml2);
+
+ Assert.assertEquals("wrong resp attr. size", 7, extractor.getAllIncludeAttributeNames().size());
+ Assert.assertEquals("Wrong attr: LoA ", "http://eidas.europa.eu/NotNotified/LoA/high",
+ extractor.getSingleAttributeValue("urn:oid:1.2.40.0.10.2.1.1.261.108"));
+ Assert.assertEquals("Wrong attr: PVP_VERSION ", "2.2",
+ extractor.getSingleAttributeValue("urn:oid:1.2.40.0.10.2.1.1.261.10"));
+ Assert.assertEquals("Wrong attr: EID_ISSUER_NATION ", cc,
+ extractor.getSingleAttributeValue("urn:oid:1.2.40.0.10.2.1.1.261.32"));
+ Assert.assertEquals("Wrong attr: eidasBind", eidasBind,
+ extractor.getSingleAttributeValue("urn:eidgvat:attributes.eidbind"));
+ Assert.assertNotNull("Wrong attr: authBlock",
+ extractor.getSingleAttributeValue("urn:eidgvat:attributes.authblock.signed"));
+ Assert.assertNotNull("Wrong attr: piiTras.Id ",
+ extractor.getSingleAttributeValue("urn:eidgvat:attributes.piiTransactionId"));
+ Assert.assertEquals("Wrong attr:EID_STATUS_LEVEL ", "http://eid.gv.at/eID/status/identity",
+ extractor.getSingleAttributeValue(PvpAttributeDefinitions.EID_IDENTITY_STATUS_LEVEL_NAME));
+
+ }
+
private void injectSzrResponse() throws Exception {
when(szrMock.getStammzahlEncrypted(any(), any())).thenReturn(vsz);
@@ -509,7 +645,7 @@ public class FullStartUpAndProcessTest {
}
- private String validateEidasNodeRequestAndBuildResponse(String eidasNodeReqToken)
+ private String validateEidasNodeRequestAndBuildResponse(String eidasNodeReqToken, String loa)
throws SpecificCommunicationException, URISyntaxException {
final SpecificCommunicationService springManagedSpecificConnectorCommunicationService =
(SpecificCommunicationService) wac.getBean(
@@ -521,17 +657,16 @@ public class FullStartUpAndProcessTest {
Assert.assertNotNull("eIDAS Node req", req);
Assert.assertEquals("Wrong CC", cc, req.getCitizenCountryCode());
- Assert.assertEquals("Wrong CC", EaafConstants.EIDAS_LOA_HIGH, req.getLevelOfAssurance());
-
-
+ Assert.assertEquals("Wrong CC", loa, req.getLevelsOfAssurance().get(0).getValue());
+
//set response from eIDAS node
BinaryLightToken respoToken = springManagedSpecificConnectorCommunicationService.putResponse(
- buildDummyAuthResponse(EidasConstants.SUCCESS_URI, req.getId()));
+ buildDummyAuthResponse(EidasConstants.SUCCESS_URI, req.getId(), loa));
return Base64Utils.encodeToString(respoToken.getTokenBytes());
}
- private AuthenticationResponse buildDummyAuthResponse(String statusCode, String reqId) throws URISyntaxException {
+ private AuthenticationResponse buildDummyAuthResponse(String statusCode, String reqId, String loa) throws URISyntaxException {
final AttributeDefinition<?> attributeDef = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final AttributeDefinition<?> attributeDef2 = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
@@ -554,7 +689,7 @@ public class FullStartUpAndProcessTest {
.statusCode(statusCode)
.inResponseTo(reqId)
.subjectNameIdFormat("afaf")
- .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .levelOfAssurance(loa)
.attributes(attributeMap)
.build();
diff --git a/ms_specific_connector/src/test/resources/config/junit_config_1_springboot.properties b/ms_specific_connector/src/test/resources/config/junit_config_1_springboot.properties
index dc2b1587..9c0de7b0 100644
--- a/ms_specific_connector/src/test/resources/config/junit_config_1_springboot.properties
+++ b/ms_specific_connector/src/test/resources/config/junit_config_1_springboot.properties
@@ -106,6 +106,7 @@ eidas.ms.sp.1.policy.hasBaseIdTransferRestriction=true
eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy
eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://eidas.proxy/endpoint
+eidas.ms.auth.eIDAS.node_v2.loa.ua.requested=http://eidas.europa.eu/NotNotified/LoA/high
## PVP2 S-Profile communication with ID Austria System
# EntityId and optional metadata of ID Austria System