aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules
diff options
context:
space:
mode:
Diffstat (limited to 'eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules')
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java12
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java59
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java200
3 files changed, 232 insertions, 39 deletions
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");
+
+ }
+
+ }
}