aboutsummaryrefslogtreecommitdiff
path: root/modules/eidas_proxy-sevice/src/main/java/at/asitplus
diff options
context:
space:
mode:
authorThomas <>2022-08-08 15:00:16 +0200
committerThomas <>2022-08-08 15:00:16 +0200
commitb54e3424a7ac9a661aae771f13cdc94086b04132 (patch)
treebdf5c77798e3532a2fc1fcc6f58e3b7dbf8e069b /modules/eidas_proxy-sevice/src/main/java/at/asitplus
parent669e1d6571b4bddcf5955597bcfe90e1523a6714 (diff)
downloadNational_eIDAS_Gateway-b54e3424a7ac9a661aae771f13cdc94086b04132.tar.gz
National_eIDAS_Gateway-b54e3424a7ac9a661aae771f13cdc94086b04132.tar.bz2
National_eIDAS_Gateway-b54e3424a7ac9a661aae771f13cdc94086b04132.zip
feat(proxy): optimize mandate support by selection mandate-mode based on requested attributes and profiles from configuration
Now it's possible to deactivte legal- or natural-person mandates by mandate-profile configuration on eIDAS-Connector level
Diffstat (limited to 'modules/eidas_proxy-sevice/src/main/java/at/asitplus')
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java231
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java2
2 files changed, 124 insertions, 109 deletions
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
index 9a0331bd..32be0e22 100644
--- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
@@ -5,6 +5,7 @@ import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
@@ -77,11 +78,13 @@ public class EidasProxyServiceController extends AbstractController implements I
private static final String ERROR_09 = "eidas.proxyservice.09";
private static final String ERROR_10 = "eidas.proxyservice.10";
private static final String ERROR_11 = "eidas.proxyservice.11";
-
+
public static final String PROTOCOL_ID = "eidasProxy";
- @Autowired ProxyEidasAttributeRegistry attrRegistry;
- @Autowired ProxyServiceAuthenticationAction responseAction;
+ @Autowired
+ ProxyEidasAttributeRegistry attrRegistry;
+ @Autowired
+ ProxyServiceAuthenticationAction responseAction;
/**
* End-point that receives authentication requests from eIDAS Node.
@@ -92,8 +95,8 @@ public class EidasProxyServiceController extends AbstractController implements I
* @throws EaafException In case of a validation or processing error
*/
@RequestMapping(value = {
- MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_POST,
- MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_REDIRECT
+ MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_POST,
+ MsProxyServiceConstants.EIDAS_HTTP_ENDPOINT_IDP_REDIRECT
},
method = { RequestMethod.POST, RequestMethod.GET })
public void receiveEidasAuthnRequest(HttpServletRequest httpReq, HttpServletResponse httpResp)
@@ -119,17 +122,18 @@ public class EidasProxyServiceController extends AbstractController implements I
.toString());
final ILightRequest eidasRequest = specificProxyCommunicationService.getAndRemoveRequest(
tokenBase64,
- ImmutableSortedSet.copyOf(attrRegistry.getCoreRegistry().getCoreAttributeRegistry().getAttributes()));
+ ImmutableSortedSet.copyOf(attrRegistry.getCoreRegistry().getCoreAttributeRegistry()
+ .getAttributes()));
if (eidasRequest == null) {
log.info("Find no eIDAS Authn. Request with stated token.");
throw new EidasProxyServiceException(ERROR_11, null);
-
- }
-
+
+ }
+
log.debug("Received eIDAS auth. request from: {}, Initializing authentication environment ... ",
eidasRequest.getSpCountryCode() != null ? eidasRequest.getSpCountryCode() : "'missing SP-country'");
log.trace("Received eIDAS requst: {}", eidasRequest);
-
+
// create pendingRequest object
pendingReq = applicationContext.getBean(ProxyServicePendingRequest.class);
pendingReq.initialize(httpReq, authConfig);
@@ -141,7 +145,7 @@ public class EidasProxyServiceController extends AbstractController implements I
revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(),
pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP,
httpReq.getRemoteAddr());
-
+
// validate eIDAS Authn. request and set into pending-request
validateEidasAuthnRequest(eidasRequest);
pendingReq.setEidasRequest(eidasRequest);
@@ -149,9 +153,9 @@ public class EidasProxyServiceController extends AbstractController implements I
// generate Service-Provider configuration from eIDAS request
final ISpConfiguration spConfig = generateSpConfigurationFromEidasRequest(eidasRequest);
- // validate eIDAS Authn. request by using eIDAS Connector specifc parameters
+ // validate eIDAS Authn. request by using eIDAS Connector specifc parameters
validateEidasAuthnRequest(spConfig, eidasRequest);
-
+
// populate pendingRequest with parameters
pendingReq.setOnlineApplicationConfiguration(spConfig);
pendingReq.setSpEntityId(spConfig.getUniqueIdentifier());
@@ -190,16 +194,16 @@ public class EidasProxyServiceController extends AbstractController implements I
public boolean generateErrorMessage(Throwable e, HttpServletRequest httpReq, HttpServletResponse httpResp,
IRequest pendingReq) throws Throwable {
if (pendingReq instanceof ProxyServicePendingRequest) {
- try {
- ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest();
-
- //build eIDAS response
- Builder lightRespBuilder = LightResponse.builder();
+ try {
+ final ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest();
+
+ // build eIDAS response
+ final Builder lightRespBuilder = LightResponse.builder();
lightRespBuilder.id(UUID.randomUUID().toString());
lightRespBuilder.inResponseToId(eidasReq.getId());
lightRespBuilder.relayState(eidasReq.getRelayState());
lightRespBuilder.issuer(authConfig.getBasicConfiguration(
- MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID));
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID));
lightRespBuilder.subject(UUID.randomUUID().toString());
lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT);
lightRespBuilder.status(ResponseStatus.builder()
@@ -223,7 +227,7 @@ public class EidasProxyServiceController extends AbstractController implements I
ProxyServicePendingRequest.class.getName());
}
-
+
return false;
}
@@ -253,11 +257,11 @@ public class EidasProxyServiceController extends AbstractController implements I
* @throws EidasProxyServiceException In case of a validation error
*/
private void validateEidasAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException {
- if (StringUtils.isEmpty(eidasRequest.getIssuer())) {
+ if (StringUtils.isEmpty(eidasRequest.getIssuer())) {
throw new EidasProxyServiceException(ERROR_05, null);
}
-
+
// TODO: validate some other stuff
}
@@ -266,23 +270,23 @@ public class EidasProxyServiceController extends AbstractController implements I
* eIDAS Connector specific validation of incoming eIDAS request.
*
* @param eidasRequest Incoming eIDAS authentication request
- * @param spConfig eIDAS Connector configuration
+ * @param spConfig eIDAS Connector configuration
* @throws EidasProxyServiceException In case of a validation error
*/
- private void validateEidasAuthnRequest(ISpConfiguration spConfig, ILightRequest eidasRequest)
- throws EidasProxyServiceException {
+ private void validateEidasAuthnRequest(ISpConfiguration spConfig, ILightRequest eidasRequest)
+ throws EidasProxyServiceException {
// check if natural-person and legal-person attributes requested in parallel
- if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, true)
- && EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)
+ if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_VALIDATION_ATTR_MDS, true)
+ && EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)
&& EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
throw new EidasProxyServiceException(ERROR_08, null);
-
+
}
-
+
// TODO: validate some other stuff
}
-
+
/**
* Generate a dummy Service-Provider configuration for processing.
*
@@ -293,55 +297,57 @@ public class EidasProxyServiceController extends AbstractController implements I
private ISpConfiguration generateSpConfigurationFromEidasRequest(ILightRequest eidasRequest)
throws EidasProxyServiceException {
try {
-
- Map<String, String> connectorConfigMap = extractRawConnectorConfiguration(eidasRequest);
-
+
+ final Map<String, String> connectorConfigMap = extractRawConnectorConfiguration(eidasRequest);
+
// check if country-code is available
- String spCountry = connectorConfigMap.get(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE);
- if (StringUtils.isEmpty(spCountry)) {
+ final String spCountry = connectorConfigMap.get(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE);
+ if (StringUtils.isEmpty(spCountry)) {
throw new EidasProxyServiceException(ERROR_07, null);
}
-
- // build FriendyName from CountryCode and SPType
+
+ // build FriendyName from CountryCode and SPType
connectorConfigMap.put(MsEidasNodeConstants.PROP_CONFIG_SP_FRIENDLYNAME,
MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID,
spCountry, eidasRequest.getSpType()));
- // build Service-Provider configuration object
- final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap, authConfig);
+ // build Service-Provider configuration object
+ final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap,
+ authConfig);
- // build bPK target from Country-Code
- final String ccCountry = authConfig.getBasicConfiguration(EidasConstants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE,
+ // build bPK target from Country-Code
+ final String ccCountry = authConfig.getBasicConfiguration(
+ EidasConstants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE,
EidasConstants.DEFAULT_MS_NODE_COUNTRY_CODE);
spConfig.setBpkTargetIdentifier(
EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry);
-
+
// set required LoA from eIDAS request
spConfig.setRequiredLoA(
eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList()));
// build mandate profiles for this specific request
buildMandateProfileConfiguration(spConfig, eidasRequest);
-
+
// map eIDAS attributes to national attributes
buildNationalRequestedAttributes(spConfig, eidasRequest);
-
+
return spConfig;
- } catch (EidasProxyServiceException e) {
+ } catch (final EidasProxyServiceException e) {
throw e;
-
+
} catch (final EaafException e) {
throw new EidasProxyServiceException(ERROR_04, new Object[] { e.getMessage() }, e);
}
}
-
private void buildNationalRequestedAttributes(
- ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) {
- boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode());
+ ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) {
+ final boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode());
spConfig.setRequestedAttributes(
Streams.concat(
eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream()
@@ -350,126 +356,133 @@ public class EidasProxyServiceController extends AbstractController implements I
.flatMap(Collection::stream)
.filter(Objects::nonNull),
attrRegistry.getAlwaysRequestedAttributes(mandatesEnabled))
- .collect(Collectors.toSet()));
+ .collect(Collectors.toSet()));
log.debug("Inject #{} attributes to request from IDA system", spConfig.getRequestedAttributes().size());
-
+
}
- private Map<String, String> extractRawConnectorConfiguration(ILightRequest eidasRequest) {
- Map<String, String> allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix(
+ private Map<String, String> extractRawConnectorConfiguration(ILightRequest eidasRequest) {
+ final Map<String, String> allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix(
MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX);
if (log.isTraceEnabled()) {
log.trace("Full-connector configuration:");
allConnectorConfigs.entrySet().stream().forEach(
el -> log.trace("Key: {} -> Value: {}", el.getKey(), el.getValue()));
-
+
}
-
- Map<String, String> connectorConfig = allConnectorConfigs.entrySet().stream()
- .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER)
+
+ final Map<String, String> connectorConfig = allConnectorConfigs.entrySet().stream()
+ .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER)
&& el.getValue().equals(eidasRequest.getIssuer()))
.findFirst()
- .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs,
+ .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs,
KeyValueUtils.getParentKey(el.getKey()) + KeyValueUtils.KEY_DELIMITER))
.orElse(new HashMap<>());
-
if (connectorConfig.isEmpty()) {
- log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ",
+ log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ",
eidasRequest.getIssuer());
-
+
// set EntityId of the requesting eIDAS Connector
connectorConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, eidasRequest.getIssuer());
-
+
// set country-code from eIDAS request
- connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE,
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE,
eidasRequest.getSpCountryCode());
-
+
// set default mandate configuration
- connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED,
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED,
String.valueOf(authConfig.getBasicConfigurationBoolean(
- MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false)));
- connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false)));
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
authConfig.getBasicConfiguration(
MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL));
- connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
authConfig.getBasicConfiguration(
MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL));
-
+
} else {
log.debug("Find specific configuration for eIDAS Connector: {}", eidasRequest.getIssuer());
-
+
}
-
+
return connectorConfig;
-
+
}
-
-
- private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest)
+
+ private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig,
+ ILightRequest eidasRequest)
throws EidasProxyServiceException {
// check if mandates are enabled
- if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, false)) {
+ if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED,
+ false)) {
injectMandateInfosIntoSpConfig(spConfig, eidasRequest);
-
- } else {
+
+ } else {
if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) {
throw new EidasProxyServiceException(ERROR_09, null);
-
- }
-
+
+ }
+
spConfig.setMandateProfiles(Collections.emptyList());
- spConfig.setMandateMode(SpMandateModes.NONE);
-
+ spConfig.setMandateMode(SpMandateModes.NONE);
+
}
}
private void injectMandateInfosIntoSpConfig(ServiceProviderConfiguration spConfig,
ILightRequest eidasRequest) throws EidasProxyServiceException {
- log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ",
+ log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ",
spConfig.getUniqueIdentifier());
- if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)
+ final List<String> legalPersonProfiles = KeyValueUtils.getListOfCsvValues(spConfig.getConfigurationValue(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL));
+ final List<String> natPersonProfiles = KeyValueUtils.getListOfCsvValues(spConfig.getConfigurationValue(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL));
+
+ if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)
&& EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
- log.debug("Find requested attributes for legal and natural persons. Injecting mandate-profiles for both ... ");
- spConfig.setMandateProfiles(ListUtils.union(
- KeyValueUtils.getListOfCsvValues(
- spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL)),
- KeyValueUtils.getListOfCsvValues(
- spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL))));
- spConfig.setMandateMode(SpMandateModes.BOTH);
-
+ log.debug(
+ "Find requested attributes for legal and natural persons. Injecting mandate-profiles for both ... ");
+ spConfig.setMandateProfiles(ListUtils.union(natPersonProfiles, legalPersonProfiles));
+
+ // set Mandate-Mode based on SP configuration
+ final boolean isLegalPersonProfile = !legalPersonProfiles.isEmpty();
+ final boolean isNaturalPersonProfile = !natPersonProfiles.isEmpty();
+ spConfig.setMandateMode(
+ isLegalPersonProfile && isNaturalPersonProfile
+ ? SpMandateModes.BOTH
+ : isLegalPersonProfile
+ ? SpMandateModes.LEGAL_FORCE
+ : SpMandateModes.NATURAL);
+
} else if (EidasProxyServiceUtils.isLegalPersonRequested(eidasRequest)) {
- //check if legal person is requested
- spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues(
- spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL)));
+ // check if legal person is requested
+ spConfig.setMandateProfiles(legalPersonProfiles);
spConfig.setMandateMode(SpMandateModes.LEGAL_FORCE);
-
+
if (spConfig.getMandateProfiles().isEmpty()) {
throw new EidasProxyServiceException(ERROR_10, null);
-
+
}
-
+
} else if (EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
- spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues(
- spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL)));
-
+ spConfig.setMandateProfiles(natPersonProfiles);
spConfig.setMandateMode(SpMandateModes.NATURAL);
-
+
}
-
-
+
if (spConfig.getMandateProfiles().isEmpty()) {
- log.debug("No mandate-profiles for issure: {}. Set mandate-mode to 'none'",
+ log.debug("No mandate-profiles for issure: {}. Set mandate-mode to 'none'",
spConfig.getUniqueIdentifier());
spConfig.setMandateMode(SpMandateModes.NONE);
-
+
} else {
log.debug("Set mandate-profiles: {} to request from issuer: {}",
spConfig.getMandateProfiles(), spConfig.getUniqueIdentifier());
-
+
}
-
+
}
}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java
index bf1c5e5f..8348558c 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
@@ -307,6 +307,8 @@ public class ProxyServiceAuthenticationAction implements IAction {
*/
private void injectJurPersonWorkaroundIfRequired(
ImmutableAttributeMap.Builder attributeMap, ILightRequest eidasReq, IAuthData authData) {
+
+ //TODO: maybe we have update that check, because we need an activation on Connector level
if (isLegalPersonWorkaroundActive() && isLegalPersonMandateAvailable(authData)
&& EidasProxyServiceUtils.isNaturalPersonRequested(eidasReq)
&& EidasProxyServiceUtils.isLegalPersonRequested(eidasReq)) {