diff options
Diffstat (limited to 'modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java')
-rw-r--r-- | modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java new file mode 100644 index 00000000..c918b7a4 --- /dev/null +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java @@ -0,0 +1,177 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, 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 "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.eidas.v2.tasks; + +import java.io.IOException; + +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.context.ApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.util.UriComponentsBuilder; + +import at.asitplus.eidas.specific.core.MsConnectorEventCodes; +import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.validator.EidasResponseValidator; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +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.EidAuthProcessDataWrapper; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.light.ILightResponse; +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; + +@Slf4j +@Component("ReceiveResponseFromeIDASNodeTask") +public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { + + @Autowired + ApplicationContext context; + + @Autowired + private IConfiguration basicConfig; + @Autowired + private EidasAttributeRegistry attrRegistry; + + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) throws TaskExecutionException { + try { + final ILightResponse eidasResponse = (ILightResponse) request.getAttribute( + Constants.DATA_FULL_EIDAS_RESPONSE); + if (eidasResponse == null) { + log.warn("NO eIDAS response-message found."); + throw new EidasSAuthenticationException("eidas.01", null); + + } + + String stagingEndpoint = pendingReq.getRawData( + MsEidasNodeConstants.EXECCONTEXT_PARAM_MSCONNECTOR_STAGING, String.class); + if (StringUtils.isNotEmpty(stagingEndpoint)) { + log.info("Find ms-connector staging to: {}. Forwarding to that endpoint ... ", stagingEndpoint); + forwardToOtherStage(response, executionContext, eidasResponse, stagingEndpoint); + + } else { + executionContext.put(MsEidasNodeConstants.EXECCONTEXT_PARAM_MSCONNECTOR_STAGING, false); + processResponseOnThatStage(executionContext, eidasResponse); + + } + + } catch (final EaafException e) { + revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_NOT_VALID); + throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e); + + } catch (final Exception e) { + log.warn("eIDAS Response processing FAILED.", e); + revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_NOT_VALID); + throw new TaskExecutionException(pendingReq, e.getMessage(), + new EidasSAuthenticationException("eidas.05", new Object[] { e.getMessage() }, e)); + + } + } + + private void forwardToOtherStage(HttpServletResponse response, ExecutionContext executionContext, + ILightResponse eidasResponse, String stagingEndpoint) throws SpecificCommunicationException, IOException { + executionContext.put(MsEidasNodeConstants.EXECCONTEXT_PARAM_MSCONNECTOR_STAGING, true); + + final SpecificCommunicationService specificConnectorCommunicationService = + (SpecificCommunicationService) context.getBean( + SpecificCommunicationDefinitionBeanNames.SPECIFIC_CONNECTOR_COMMUNICATION_SERVICE.toString()); + BinaryLightToken token = specificConnectorCommunicationService.putResponse(eidasResponse); + final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token); + + final UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(stagingEndpoint); + redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64); + + log.debug("Forward to other stage .... "); + response.sendRedirect(redirectUrl.build().encode().toString()); + + } + + private void processResponseOnThatStage(ExecutionContext executionContext, ILightResponse eidasResponse) + throws EaafException { + log.debug("Receive eIDAS response with RespId:" + eidasResponse.getId() + " for ReqId:" + eidasResponse + .getInResponseToId()); + log.trace("Full eIDAS-Resp: " + eidasResponse.toString()); + revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE, eidasResponse + .getId()); + + // check response StatusCode + if (!eidasResponse.getStatus().getStatusCode().equals(Constants.SUCCESS_URI)) { + log.info("Receice eIDAS Response with StatusCode:" + eidasResponse.getStatus().getStatusCode() + + " Subcode:" + eidasResponse.getStatus().getSubStatusCode() + " Msg:" + eidasResponse.getStatus() + .getStatusMessage()); + throw new EidasSAuthenticationException("eidas.02", new Object[] { eidasResponse.getStatus() + .getStatusCode(), eidasResponse.getStatus().getStatusMessage() }); + + } + + // extract all Attributes from response + + // ********************************************************** + // ******* MS-specificresponse validation ********** + // ********************************************************** + final String spCountry = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, + "AT"); + final String citizenCountryCode = (String) executionContext.get( + MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY); + EidasResponseValidator.validateResponse(pendingReq, eidasResponse, spCountry, citizenCountryCode, + attrRegistry); + + // ********************************************************** + // ******* Store resonse infos into session object ********** + // ********************************************************** + + // update MOA-Session data with received information + log.debug("Store eIDAS response information into pending-request."); + final EidAuthProcessDataWrapper authProcessData = pendingReq.getSessionData(EidAuthProcessDataWrapper.class); + authProcessData.setQaaLevel(eidasResponse.getLevelOfAssurance()); + authProcessData.setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse); + + + //inject set flag to inject + authProcessData.setTestIdentity( + basicConfig.getBasicConfigurationBoolean(Constants.CONIG_PROPS_EIDAS_IS_TEST_IDENTITY, false)); + + // store MOA-session to database + requestStoreage.storePendingRequest(pendingReq); + + revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_VALID); + + } + +} |