aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java346
1 files changed, 346 insertions, 0 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java
new file mode 100644
index 000000000..70f425148
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java
@@ -0,0 +1,346 @@
+package at.gv.egovernment.moa.id.protocols.oauth20;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.oauth.jsontoken.JsonToken;
+import net.oauth.jsontoken.crypto.Signer;
+
+import org.w3c.dom.Element;
+
+import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate;
+import at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType;
+import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType;
+import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName;
+import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType;
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.exception.BuildException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ServerErrorException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20UnauthorizedClientException;
+import at.gv.egovernment.moa.id.protocols.oauth20.requests.OAuth20TokenRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AttributeExtractor;
+import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
+import at.gv.egovernment.moa.id.util.IdentityLinkReSigner;
+import at.gv.egovernment.moa.id.util.MandateBuilder;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+
+import com.google.gson.JsonObject;
+
+public class OAuth20TokenAction implements IAction {
+
+ private int expirationTime = 5 * 60; // in seconds
+
+ public class Pair<T1, T2> {
+ private T1 first;
+ private T2 second;
+
+ public Pair(T1 newFirst, T2 newSecond) {
+ first = newFirst;
+ second = newSecond;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+ }
+
+ public String processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp,
+ AuthenticationSession moasession) throws MOAIDException {
+
+ AuthenticationSession session = null;
+ try {
+ OAuth20TokenRequest oAuthRequest = (OAuth20TokenRequest) req;
+
+ session = AuthenticationSessionStoreage.getSession(oAuthRequest.getCode());
+ if (session == null) {
+ throw new OAuth20UnauthorizedClientException();
+ }
+
+ OAuth20SessionObject auth20SessionObject = session.getoAuth20SessionObject();
+ Logger.debug("Loaded OAuth20SessionObject from session: " + auth20SessionObject);
+
+ // do checking for different grant types and code
+ if (!auth20SessionObject.getCode().equals(oAuthRequest.getCode())) {
+ throw new OAuth20UnauthorizedClientException();
+
+ }
+
+ final String accessToken = UUID.randomUUID().toString();
+
+ // create response
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(OAuth20Constants.RESPONSE_ACCESS_TOKEN, accessToken);
+ params.put(OAuth20Constants.RESPONSE_TOKEN_TYPE, OAuth20Constants.RESPONSE_TOKEN_TYPE_VALUE_BEARER);
+ params.put(OAuth20Constants.RESPONSE_EXPIRES_IN, this.expirationTime);
+
+ // build id token and scope
+ Pair<String, String> pair = buildIdToken(auth20SessionObject.getScope(), oAuthRequest, session);
+ Logger.debug("RESPONSE ID_TOKEN: " + pair.getFirst());
+ params.put(OAuth20Constants.RESPONSE_ID_TOKEN, pair.getFirst());
+ Logger.debug("RESPONSE SCOPE: " + pair.getSecond());
+ params.put(OAuth20Constants.PARAM_SCOPE, pair.getSecond());
+
+ // create response
+ JsonObject jsonObject = new JsonObject();
+ OAuth20Util.addProperytiesToJsonObject(jsonObject, params);
+ String jsonResponse = jsonObject.toString();
+ Logger.debug("JSON Response: " + jsonResponse);
+
+ // write respone to http response
+ httpResp.setContentType("application/json");
+ httpResp.setStatus(HttpServletResponse.SC_OK);
+ httpResp.getOutputStream().print(jsonResponse);
+ httpResp.getOutputStream().close();
+
+ return null;
+ }
+ catch (Exception e) {
+ throw new OAuth20ServerErrorException();
+ }
+ finally {
+ if (session != null) {
+ // destroy session for clean up
+ try {
+ Logger.debug("Going to destroy session: " + session.getSessionID());
+ AuthenticationSessionStoreage.destroySession(session.getSessionID());
+ }
+ catch (MOADatabaseException e) {
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls
+ * .IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ public String getDefaultActionName() {
+ return OAuth20Protocol.TOKEN_ACTION;
+ }
+
+ private Pair<String, String> buildIdToken(String scope, OAuth20TokenRequest oAuthRequest, AuthenticationSession session)
+ throws Exception {
+ OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oAuthRequest.getOAURL());
+ AuthenticationData authData = AuthenticationServer.buildAuthenticationData(session, oaParam, oAuthRequest.getTarget());
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ StringBuilder resultScopes = new StringBuilder();
+ // always fill with open id
+ this.fillScopeOpenId(params, authData);
+ resultScopes.append("openId");
+
+ for (String s : scope.split(" ")) {
+
+ try {
+ if (s.equalsIgnoreCase("profile")) {
+ this.fillScopeProfile(params, authData);
+ resultScopes.append(" profile");
+ } else if (s.equalsIgnoreCase("eID")) {
+ this.fillScopeEID(params, authData, session);
+ resultScopes.append(" eID");
+ } else if (s.equalsIgnoreCase("eID_gov") && oaParam.getBusinessService()) {
+ this.fillScopeEID_GOV(params, authData, session);
+ resultScopes.append(" eID_gov");
+ } else if (s.equalsIgnoreCase("mandate") && session.getUseMandate() && oaParam.getBusinessService()) {
+ this.fillScopeMandate(params, oaParam, authData, session);
+ resultScopes.append(" mandate");
+ }
+ }
+ catch (Exception e) {
+ Logger.warn(e.getMessage(), e);
+ }
+ // TODO parser STORK
+ }
+
+ // add properties and sign
+ // HmacSHA256Signer signer = new HmacSHA256Signer("testSigner", "key_id",
+ // "super_secure_pwd".getBytes());
+ // Signer signer = OAuth20Util.loadSigner(authData.getIssuer(), oaParam.getoAuth20Config());
+ Signer signer = OAuth20Util.loadSigner(authData.getIssuer());
+ JsonToken token = new JsonToken(signer);
+ OAuth20Util.addProperytiesToJsonObject(token.getPayloadAsJsonObject(), params);
+ return new Pair<String, String>(token.serializeAndSign(), resultScopes.toString());
+ }
+
+ private void fillScopeProfile(Map<String, Object> params, AuthenticationData authData) {
+ params.put("given_name", authData.getGivenName());
+ params.put("family_name", authData.getFamilyName());
+ params.put("birthdate", authData.getDateOfBirth());
+ }
+
+ private void fillScopeOpenId(Map<String, Object> params, AuthenticationData authData) {
+ params.put("iss", authData.getIssuer());
+ params.put("sub", authData.getBPK());
+ // params.put("aud", ""); // not used
+ params.put("exp", (long) (new Date().getTime() / 1000 + this.expirationTime));
+ params.put("iat", (long) (new Date().getTime() / 1000));
+ params.put("auth_time", (long) (authData.getTimestamp().getTime() / 1000));
+ // params.put("acr", ""); //?
+ }
+
+ private void fillScopeEID(Map<String, Object> params, AuthenticationData authData, AuthenticationSession session) throws Exception {
+ params.put(PVPConstants.EID_CCS_URL_FRIENDLY_NAME, authData.getBkuURL());
+ // params.put("ENC-BPK-LIST", ); // not used
+ // params.put("MAIL", ); //not used
+ // params.put("TEL", ); //not used
+
+ params.put(PVPConstants.EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME, 4);
+ params.put(PVPConstants.EID_ISSUING_NATION_FRIENDLY_NAME, "AT");
+ params.put(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, authData.getBPKType());
+ params.put(PVPConstants.EID_AUTH_BLOCK_FRIENDLY_NAME, Base64Utils.encode(session.getAuthBlock().getBytes()));
+ params.put(PVPConstants.EID_SIGNER_CERTIFICATE_FRIENDLY_NAME, Base64Utils.encode(session.getEncodedSignerCertificate()));
+ // params.put(PVPConstants.EID_STORK_TOKEN_FRIENDLY_NAME, ); //not used
+
+ // bpk
+ String bpk = authData.getBPK();
+ String type = authData.getBPKType();
+ if (type.startsWith(Constants.URN_PREFIX_WBPK))
+ type = type.substring((Constants.URN_PREFIX_WBPK + "+").length());
+ else if (type.startsWith(Constants.URN_PREFIX_CDID)) type = type.substring((Constants.URN_PREFIX_CDID + "+").length());
+ if (bpk.length() > PVPConstants.BPK_MAX_LENGTH) {
+ bpk = bpk.substring(0, PVPConstants.BPK_MAX_LENGTH);
+ }
+ params.put(PVPConstants.BPK_FRIENDLY_NAME, type + ":" + bpk);
+ }
+
+ private void fillScopeEID_GOV(Map<String, Object> params, AuthenticationData authData, AuthenticationSession session)
+ throws Exception {
+ params.put(PVPConstants.EID_SOURCE_PIN_FRIENDLY_NAME, authData.getIdentificationValue());
+ params.put(PVPConstants.EID_SOURCE_PIN_TYPE_FRIENDLY_NAME, authData.getIdentificationType());
+
+ IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance();
+ Element resignedilAssertion = identitylinkresigner.resignIdentityLink(authData.getIdentityLink().getSamlAssertion());
+ params.put(PVPConstants.EID_IDENTITY_LINK_FRIENDLY_NAME,
+ Base64Utils.encode(DOMUtils.serializeNode(resignedilAssertion).getBytes()));
+ }
+
+ private void fillScopeMandate(Map<String, Object> params, OAAuthParameter oaParam, AuthenticationData authData,
+ AuthenticationSession session) {
+ Element mandate = session.getMandate();
+
+ if (mandate == null) {
+ throw new OAuth20ServerErrorException();
+ }
+ Mandate mandateObject = MandateBuilder.buildMandate(mandate);
+ if (mandateObject == null) {
+ throw new OAuth20ServerErrorException();
+ }
+
+ params.put(PVPConstants.MANDATE_TYPE_FRIENDLY_NAME, mandateObject.getAnnotation());
+ params.put(PVPConstants.MANDATE_REFERENCE_VALUE_FRIENDLY_NAME, mandateObject.getMandateID());
+
+ // natural person
+ PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson();
+ if (physicalPerson != null && physicalPerson.getIdentification().size() != 0) {
+ IdentificationType id = physicalPerson.getIdentification().get(0);
+ params.put(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_FRIENDLY_NAME, id.getValue().getValue());
+ params.put(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, id.getType());
+
+ try {
+ String bpk;
+ if (id.getType().equals(Constants.URN_PREFIX_BASEID)) {
+ if (session.getBusinessService()) {
+ bpk = new BPKBuilder().buildWBPK(id.getValue().getValue(), oaParam.getIdentityLinkDomainIdentifier());
+ } else {
+ bpk = new BPKBuilder().buildBPK(id.getValue().getValue(), oaParam.getTarget());
+ }
+ } else {
+ bpk = id.getValue().getValue();
+ }
+ params.put(PVPConstants.MANDATE_NAT_PER_BPK_FRIENDLY_NAME, bpk);
+ }
+ catch (BuildException e) {
+ // ignore
+ }
+
+ // params.put(PVPConstants.MANDATE_NAT_PER_ENC_BPK_LIST_FRIENDLY_NAME, ); //not used
+
+ StringBuilder sb = new StringBuilder();
+ Iterator<FamilyName> fNamesit = physicalPerson.getName().getFamilyName().iterator();
+
+ while (fNamesit.hasNext()) {
+ sb.append(" " + fNamesit.next().getValue());
+ }
+ params.put(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME, sb.toString());
+
+ sb = new StringBuilder();
+ Iterator<String> gNamesit = physicalPerson.getName().getGivenName().iterator();
+
+ while (gNamesit.hasNext()) {
+ sb.append(" " + gNamesit.next());
+ }
+ params.put(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, sb.toString());
+
+ try {
+ DateFormat mandateFormat = new SimpleDateFormat(MandateBuilder.MANDATE_DATE_OF_BIRTH_FORMAT);
+ Date date = mandateFormat.parse(physicalPerson.getDateOfBirth());
+ DateFormat pvpDateFormat = new SimpleDateFormat(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_FORMAT_PATTERN);
+ String dateString = pvpDateFormat.format(date);
+ params.put(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, dateString);
+ }
+ catch (ParseException e) {
+ // ignore
+ }
+
+ }
+
+ // legal person
+ CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody();
+ if (corporation != null && corporation.getIdentification().size() != 0) {
+ IdentificationType id = corporation.getIdentification().get(0);
+ params.put(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME, id.getValue().getValue());
+ params.put(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, id.getType());
+ params.put(PVPConstants.MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME, corporation.getFullName());
+ }
+
+ String oid = AttributeExtractor.extractSAMLAttributeOA(EXT_SAML_MANDATE_OID, session);
+ if (oid != null) {
+ params.put(PVPConstants.MANDATE_PROF_REP_OID_FRIENDLY_NAME, oid);
+ }
+
+ String text = AttributeExtractor.extractSAMLAttributeOA(EXT_SAML_MANDATE_OIDTEXTUALDESCRIPTION, session);
+
+ if (text != null) {
+ params.put(PVPConstants.MANDATE_PROF_REP_DESC_FRIENDLY_NAME, oid);
+ }
+
+ // params.put("MANDATE-FULL-MANDATE-LIST", ); // not used
+
+ }
+}