package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; import at.gv.egiz.eaaf.core.impl.idp.builder.attributes.BPKAttributeBuilder; import at.gv.egiz.eaaf.core.impl.utils.Random; import at.gv.egiz.eid4u.api.attributes.Definitions; import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionWrapper; import at.gv.egovernment.moa.id.auth.modules.eidas.eID4UConstants; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SimpleEidasAttributeGenerator; import at.gv.egovernment.moa.id.protocols.eidas.EIDASData; import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants; import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20SessionObject; import at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20AuthAction; import at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20AuthRequest; import at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20Protocol; import at.gv.egovernment.moa.id.util.CookieUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; import eu.eidas.auth.commons.attribute.ImmutableAttributeMap.Builder; @Component("CollectAddtionalAttributesTask") public class CollectAddtionalAttributesTask extends AbstractAuthServletTask { @Autowired private OAuth20AuthAction openIDAuthAction; @Autowired private ITransactionStorage transactionStorage; @Autowired private AuthenticationDataBuilder authDataBuilder; @Override public void execute(ExecutionContext context, HttpServletRequest httpReq, HttpServletResponse httpResp) throws TaskExecutionException { try{ context.put(eID4UConstants.PROCESS_CONTEXT_FLAG_EID4U_AP_ACCESS, false); if (pendingReq instanceof EIDASData) { EIDASData eidasReq = (EIDASData) pendingReq; Logger.debug("Find eIDAS Auth. Req. Check if eID4U attributes are requested ..."); //select all eID4U attributes from requested attributes Builder reqEid4uAttrListBuilder = ImmutableAttributeMap.builder(); ImmutableAttributeMap reqAttrList = eidasReq.getEidasRequestedAttributes(); for (String el : Definitions.EID4UATTRIBUTEELIST) { if(reqAttrList.getAttributeValuesByNameUri(el) != null) { Logger.debug("Find eID4U attr: " + el); reqEid4uAttrListBuilder.put(reqAttrList.getDefinitionByNameUri(el)); } } //collect eID4U attributes, if some attributes are selected before ImmutableAttributeMap reqEid4uAttrList = reqEid4uAttrListBuilder.build(); if (reqEid4uAttrList != null && reqEid4uAttrList.size() > 0) { Logger.info("Starting eID4U attribute collection process ... "); //mark execution context with eID4U AP flag context.put(eID4UConstants.PROCESS_CONTEXT_FLAG_EID4U_AP_ACCESS, true); //load connection parameters to TUG String uniqueID = authConfig.getBasicConfiguration(eID4UConstants.CONFIG_PROPS_AP_CONSENT_ENTITYID); String redirectURI = authConfig.getBasicConfiguration(eID4UConstants.CONFIG_PROPS_AP_CONSENT_URL); String scopes = authConfig.getBasicConfiguration(eID4UConstants.CONFIG_PROPS_AP_SCOPES); if (MiscUtil.isEmpty(scopes)) { //generate scope from attributes //TODO extract 'scopes' from requested attributes Logger.warn("Dynamic 'scope' generation is currently NOT supported"); } Logger.debug("Load eID4U AP-Config:" + " EntityID: " + uniqueID + " RedirectURL:" + redirectURI + " Scopes: " + scopes); /* *build openID and set connect token */ //generate fake OpenID_Connect request OAuth20AuthRequest fakeOpenIDReq = new OAuth20AuthRequest(); fakeOpenIDReq.initialize(httpReq, authConfig); fakeOpenIDReq.setSPEntityId(uniqueID); fakeOpenIDReq.setModule(OAuth20Protocol.NAME); fakeOpenIDReq.setOnlineApplicationConfiguration(authConfig.getServiceProviderConfiguration(uniqueID)); fakeOpenIDReq.setScope("openId profile"); //populate with SessionData fakeOpenIDReq.setRawDataToTransaction( pendingReq.getSessionData(AuthenticationSessionWrapper.class) .getKeyValueRepresentationFromAuthSession()); //generate authData IAuthData authData = authDataBuilder.buildAuthenticationData(fakeOpenIDReq); //generate OpenIDConenct token String accessToken = Random.nextHexRandom32(); OAuth20SessionObject o = new OAuth20SessionObject(); o.setScope(fakeOpenIDReq.getScope()); o.setCode(accessToken); Map idToken = openIDAuthAction.generateIDToken(o, fakeOpenIDReq, authData, accessToken); o.setAuthDataSession(idToken); transactionStorage.put(accessToken, o, -1); //forward to TUG httpResp.setStatus(HttpServletResponse.SC_FOUND); redirectURI = addURLParameter(redirectURI, OAuth20Constants.PARAM_OPENID_CODE, accessToken); redirectURI = addURLParameter(redirectURI, OAuth20Constants.PARAM_SCOPE, scopes); redirectURI = addURLParameter(redirectURI, OAuth20Constants.PARAM_STATE, pendingReq.getPendingRequestId()); redirectURI = addURLParameter(redirectURI, OAuth20Constants.PARAM_REDIRECT_URI, pendingReq.getAuthURL() + eID4UConstants.HTTP_ENDPOINT_AP_CONSENT_RETURN); final String finalUrl = redirectURI; httpResp.addHeader("Location", finalUrl); Logger.debug("REDIRECT TO: " + finalUrl.toString()); //set session cookie, because eID4U AP from TUG maybe not support pendingReqIds on request level CookieUtils.setCookie(httpReq, httpResp, eID4UConstants.HTTP_TRANSACTION_COOKIE_NAME, pendingReq.getPendingRequestId(), -1); //set user's bPK into pendingRequst because TUG AttributeProvider needs it pendingReq.setRawDataToTransaction( eID4UConstants.PROCESS_CONTEXT_USERS_BPK_EID4U_ATTRPROVIDER, new BPKAttributeBuilder().build( fakeOpenIDReq.getServiceProviderConfiguration(), authData, new SimpleEidasAttributeGenerator())); requestStoreage.storePendingRequest(pendingReq); } else Logger.debug("No eID4U attributes found. Skip eID4U attribute collection"); } else Logger.debug("No eIDAS Request found. Skip eID4U attribute collection"); } catch (Exception e) { Logger.error("eID4U AttributeProvider communication FAILED.", e); throw new TaskExecutionException(pendingReq, "eID4U AttributeProvider communication FAILED", e); } } }