diff options
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CollectAddtionalAttributesTask.java')
-rw-r--r-- | id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CollectAddtionalAttributesTask.java | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CollectAddtionalAttributesTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CollectAddtionalAttributesTask.java new file mode 100644 index 000000000..a58bc4f8d --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CollectAddtionalAttributesTask.java @@ -0,0 +1,181 @@ +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.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.common.collect.UnmodifiableIterator; + +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.eid4u.utils.AttributeScopeMapper; +import at.gv.egovernment.moa.id.protocols.builder.attributes.SimpleStringAttributeGenerator; +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; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap.ImmutableAttributeEntry; + +@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 + scopes = mapReqAttributesIntoScopes(reqEid4uAttrList); + + } + + 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<String, Object> 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 SimpleStringAttributeGenerator())); + 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); + + } + + } + + private String mapReqAttributesIntoScopes(ImmutableAttributeMap reqEid4uAttrList) { + String result = StringUtils.EMPTY; + UnmodifiableIterator<ImmutableAttributeEntry<?>> it = reqEid4uAttrList.entrySet().iterator(); + while (it.hasNext()) { + ImmutableAttributeEntry<?> el = it.next(); + String scope = AttributeScopeMapper.getInstance().getTUGScopesForAttribute( + el.getKey().getNameUri().toString()); + + if (result.isEmpty()) + result = scope; + else + result += " " + scope; + + } + + return result; + } + +} |