aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2014-01-20 10:32:32 +0100
committerThomas Lenz <tlenz@iaik.tugraz.at>2014-01-20 10:32:32 +0100
commit4216a1b9910506f2699a5a7cfa38be9762d654be (patch)
tree003858361013aa576be8be58173973361268f31c /id/server/idserverlib/src/main/java/at/gv/egovernment
parent0652e7c7a912804fada38062561931e16cc09026 (diff)
downloadmoa-id-spss-4216a1b9910506f2699a5a7cfa38be9762d654be.tar.gz
moa-id-spss-4216a1b9910506f2699a5a7cfa38be9762d654be.tar.bz2
moa-id-spss-4216a1b9910506f2699a5a7cfa38be9762d654be.zip
Exthex OAuth second version
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java3
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java349
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java23
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java161
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java29
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java27
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java99
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java62
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java94
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java27
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java62
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java7
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java (renamed from id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20AuthAction.java)74
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java (renamed from id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20AuthRequest.java)4
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java (renamed from id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20BaseRequest.java)9
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java (renamed from id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Protocol.java)5
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java164
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java (renamed from id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20TokenRequest.java)4
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IAttributeGenerator.java11
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IPVPAttributeBuilder.java8
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/SamlAttributeGenerator.java (renamed from id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java)36
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/AttributeException.java11
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/InvalidDateFormatAttributeException.java13
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/NoMandateDataAttributeException.java10
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/UnavailableAttributeException.java18
31 files changed, 1055 insertions, 405 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java
index 58d1ba0df..556d26c67 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java
@@ -80,9 +80,6 @@ public class MOAIDAuthInitializer {
MailcapCommandMap mc = new MailcapCommandMap();
CommandMap.setDefaultCommandMap(mc);
- Logger.info("Loading security providers.");
- //IAIK.addAsProvider();
-
// create some properties and get the default Session
Properties props = new Properties();
props.put("mail.smtp.host", "localhost");
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
deleted file mode 100644
index 22ed20d70..000000000
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20TokenAction.java
+++ /dev/null
@@ -1,349 +0,0 @@
-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.ConfigurationDBUtils;
-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 {
- ConfigurationDBUtils.closeSession();
-
-// 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
-
- }
-}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java
new file mode 100644
index 000000000..6aeac1247
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/Pair.java
@@ -0,0 +1,23 @@
+package at.gv.egovernment.moa.id.protocols.oauth20;
+
+public class Pair<P1, P2> {
+ private final P1 first;
+ private final P2 second;
+
+ private Pair(final P1 newFirst, final P2 newSecond) {
+ this.first = newFirst;
+ this.second = newSecond;
+ }
+
+ public P1 getFirst() {
+ return this.first;
+ }
+
+ public P2 getSecond() {
+ return this.second;
+ }
+
+ public static <P1, P2> Pair<P1, P2> newInstance(final P1 newFirst, final P2 newSecond) {
+ return new Pair<P1, P2>(newFirst, newSecond);
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java
new file mode 100644
index 000000000..6e5d0c2f0
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java
@@ -0,0 +1,161 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.oauth20.Pair;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.BPKAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDAuthBlock;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDCcsURL;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDCitizenQAALevelAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDIdentityLinkBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDIssuingNationAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSectorForIDAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSignerCertificate;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSourcePIN;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.EIDSourcePINType;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateLegalPersonFullNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateLegalPersonSourcePinAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateLegalPersonSourcePinTypeAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonBPKAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonBirthDateAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonFamilyNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonGivenNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonSourcePinAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateNaturalPersonSourcePinTypeAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateProfRepDescAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateProfRepOIDAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateReferenceValueAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.MandateTypeAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+import at.gv.egovernment.moa.logging.Logger;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+public final class OAuth20AttributeBuilder {
+
+ private OAuth20AttributeBuilder() {
+ throw new InstantiationError();
+ }
+
+ private static IAttributeGenerator<Pair<String, JsonPrimitive>> generator = new IAttributeGenerator<Pair<String, JsonPrimitive>>() {
+
+ public Pair<String, JsonPrimitive> buildStringAttribute(final String friendlyName, final String name, final String value) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(value));
+ }
+
+ public Pair<String, JsonPrimitive> buildIntegerAttribute(final String friendlyName, final String name, final int value) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(value));
+ }
+
+ public Pair<String, JsonPrimitive> buildLongAttribute(final String friendlyName, final String name, final long value) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(value));
+ }
+
+ public Pair<String, JsonPrimitive> buildEmptyAttribute(final String friendlyName, final String name) {
+ return Pair.newInstance(friendlyName, new JsonPrimitive(""));
+ }
+
+ };
+
+ private static final List<IAttributeBuilder> buildersOpenId = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersProfile = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersEID = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersEIDGov = new ArrayList<IAttributeBuilder>();
+ private static final List<IAttributeBuilder> buildersMandate = new ArrayList<IAttributeBuilder>();
+
+ static {
+ // openId
+ buildersOpenId.add(new OpenIdIssuerAttribute());
+ buildersOpenId.add(new OpenIdSubjectIdentifierAttribute());
+ buildersOpenId.add(new OpenIdExpirationTimeAttribute());
+ buildersOpenId.add(new OpenIdIssueInstantAttribute());
+ buildersOpenId.add(new OpenIdAuthenticationTimeAttribute());
+
+ // profile
+ buildersProfile.add(new ProfileGivenNameAttribute());
+ buildersProfile.add(new ProfileFamilyNameAttribute());
+ buildersProfile.add(new ProfileDateOfBirthAttribute());
+
+ // EID
+ buildersEID.add(new EIDCcsURL());
+ buildersEID.add(new EIDCitizenQAALevelAttributeBuilder());
+ buildersEID.add(new EIDIssuingNationAttributeBuilder());
+ buildersEID.add(new EIDSectorForIDAttributeBuilder());
+ buildersEID.add(new EIDAuthBlock());
+ buildersEID.add(new EIDSignerCertificate());
+ buildersEID.add(new BPKAttributeBuilder());
+
+ // eID_gov
+ buildersEIDGov.add(new EIDSourcePIN());
+ buildersEIDGov.add(new EIDSourcePINType());
+ buildersEIDGov.add(new EIDIdentityLinkBuilder());
+
+ // mandate
+ buildersMandate.add(new MandateTypeAttributeBuilder());
+ buildersMandate.add(new MandateReferenceValueAttributeBuilder());
+
+ buildersMandate.add(new MandateNaturalPersonSourcePinAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonSourcePinTypeAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonBPKAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonFamilyNameAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonGivenNameAttributeBuilder());
+ buildersMandate.add(new MandateNaturalPersonBirthDateAttributeBuilder());
+
+ buildersMandate.add(new MandateLegalPersonSourcePinAttributeBuilder());
+ buildersMandate.add(new MandateLegalPersonSourcePinTypeAttributeBuilder());
+ buildersMandate.add(new MandateLegalPersonFullNameAttributeBuilder());
+
+ buildersMandate.add(new MandateProfRepOIDAttributeBuilder());
+ buildersMandate.add(new MandateProfRepDescAttributeBuilder());
+ }
+
+ private static void addAttibutes(final List<IAttributeBuilder> builders, final JsonObject jsonObject,
+ final AuthenticationSession authSession, final OAAuthParameter oaParam, final AuthenticationData authData) {
+ for (IAttributeBuilder b : builders) {
+ try {
+ Pair<String, JsonPrimitive> attribute = b.build(authSession, oaParam, authData, generator);
+ if (attribute != null && !StringUtils.isEmpty(attribute.getSecond().getAsString())) {
+ jsonObject.add(attribute.getFirst(), attribute.getSecond());
+ }
+ }
+ catch (AttributeException e) {
+ Logger.warn("Cannot add attribute " + b.getName(), e);
+ }
+ }
+ }
+
+ public static void addScopeOpenId(final JsonObject jsonObject, final AuthenticationSession authSession,
+ final OAAuthParameter oaParam, final AuthenticationData authData) {
+ addAttibutes(buildersOpenId, jsonObject, authSession, oaParam, authData);
+ }
+
+ public static void addScopeProfile(final JsonObject jsonObject, final AuthenticationSession authSession,
+ final OAAuthParameter oaParam, final AuthenticationData authData) {
+ addAttibutes(buildersProfile, jsonObject, authSession, oaParam, authData);
+ }
+
+ public static void addScopeEID(final JsonObject jsonObject, final AuthenticationSession authSession,
+ final OAAuthParameter oaParam, final AuthenticationData authData) {
+ addAttibutes(buildersEID, jsonObject, authSession, oaParam, authData);
+ }
+
+ public static void addScopeEIDGov(final JsonObject jsonObject, final AuthenticationSession authSession,
+ final OAAuthParameter oaParam, final AuthenticationData authData) {
+ addAttibutes(buildersEIDGov, jsonObject, authSession, oaParam, authData);
+ }
+
+ public static void addScopeMandate(final JsonObject jsonObject, final AuthenticationSession authSession,
+ final OAAuthParameter oaParam, final AuthenticationData authData) {
+ addAttibutes(buildersMandate, jsonObject, authSession, oaParam, authData);
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java
new file mode 100644
index 000000000..566257122
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdAuthenticationTimeAttribute.java
@@ -0,0 +1,25 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdAuthenticationTimeAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "auth_time";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildLongAttribute(this.getName(), "", ((long) (authData.getTimestamp().getTime() / 1000)));
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java
new file mode 100644
index 000000000..bb1a25acc
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdExpirationTimeAttribute.java
@@ -0,0 +1,29 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import java.util.Date;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdExpirationTimeAttribute implements IAttributeBuilder {
+
+ public static final int expirationTime = 5 * 60; // in seconds
+
+ public String getName() {
+ return "exp";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildLongAttribute(this.getName(), "", (long) (new Date().getTime() / 1000 + expirationTime));
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java
new file mode 100644
index 000000000..f85f1d39c
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssueInstantAttribute.java
@@ -0,0 +1,27 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import java.util.Date;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdIssueInstantAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "iat";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildLongAttribute(this.getName(), "", (long) (new Date().getTime() / 1000));
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java
new file mode 100644
index 000000000..e12d2e718
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdIssuerAttribute.java
@@ -0,0 +1,25 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdIssuerAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "iss";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getIssuer());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java
new file mode 100644
index 000000000..36efb18e9
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OpenIdSubjectIdentifierAttribute.java
@@ -0,0 +1,25 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class OpenIdSubjectIdentifierAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "sub";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getBPK());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java
new file mode 100644
index 000000000..b9d7b984e
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileDateOfBirthAttribute.java
@@ -0,0 +1,25 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class ProfileDateOfBirthAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "birthdate";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getDateOfBirth());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java
new file mode 100644
index 000000000..eef4931bf
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileFamilyNameAttribute.java
@@ -0,0 +1,25 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class ProfileFamilyNameAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "family_name";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getFamilyName());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java
new file mode 100644
index 000000000..8cb13b912
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/ProfileGivenNameAttribute.java
@@ -0,0 +1,25 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.attributes;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.AuthenticationData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+public class ProfileGivenNameAttribute implements IAttributeBuilder {
+
+ public String getName() {
+ return "given_name";
+ }
+
+ public <ATT> ATT build(AuthenticationSession authSession, OAAuthParameter oaParam, AuthenticationData authData,
+ IAttributeGenerator<ATT> g) throws AttributeException {
+ return g.buildStringAttribute(this.getName(), "", authData.getGivenName());
+ }
+
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return g.buildEmptyAttribute(this.getName(), "");
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java
new file mode 100644
index 000000000..9755e3c0a
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Signer.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ */
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+
+import net.oauth.jsontoken.crypto.AbstractSigner;
+import net.oauth.jsontoken.crypto.RsaSHA256Signer;
+import net.oauth.jsontoken.crypto.SignatureAlgorithm;
+
+/**
+ * Signer that can sign byte arrays using a {@link PrivateKey} and SHA-256. <br/>
+ * This is something like a copy of the {@link RsaSHA256Signer}.
+ *
+ */
+public class OAuth20SHA256Signer extends AbstractSigner implements OAuthSigner {
+
+ private final Signature signature;
+ private final PrivateKey signingKey;
+ private final OAuthSignatureAlgorithm algorithm;
+
+ /**
+ * Public constructor.
+ *
+ * @param issuer
+ * The id of this signer, to be included in the JSON Token's envelope.
+ * @param keyId
+ * The id of the key used by this signer, to be included in the JSON Token's
+ * envelope.
+ * @param key
+ * the private key to be used for signing.
+ * @throws InvalidKeyException
+ * if the key is unsuitable for RSA signing.
+ */
+ public OAuth20SHA256Signer(final String issuer, final String keyId, final PrivateKey key) throws InvalidKeyException {
+ super(issuer, keyId);
+
+ this.signingKey = key;
+ this.algorithm = OAuth20SignatureUtil.findSignature(key);
+
+ try {
+ this.signature = this.algorithm.getSignatureInstance();
+ this.signature.initSign(signingKey);
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ catch (NoSuchProviderException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see net.oauth.jsontoken.crypto.Signer#getSignatureAlgorithm()
+ */
+ public SignatureAlgorithm getSignatureAlgorithm() {
+ // it is fine to return RS256 because we overwrite the JsonToken for the algorithm name. But
+ // we need the internal SHA256 which is used.
+ return SignatureAlgorithm.RS256;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see net.oauth.jsontoken.crypto.Signer#sign(byte[])
+ */
+ public byte[] sign(byte[] source) throws SignatureException {
+ try {
+ signature.initSign(signingKey);
+ }
+ catch (InvalidKeyException e) {
+ throw new RuntimeException("key somehow became invalid since calling the constructor");
+ }
+ signature.update(source);
+ return signature.sign();
+ }
+
+ public OAuthSignatureAlgorithm getOAuthSignatureAlgorithm() {
+ return this.algorithm;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java
new file mode 100644
index 000000000..e7e18cbd9
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SHA256Verifier.java
@@ -0,0 +1,62 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+
+import net.oauth.jsontoken.crypto.RsaSHA256Verifier;
+import net.oauth.jsontoken.crypto.Verifier;
+
+/**
+ * A verifier that can verify signatures on byte arrays using a {@link PublicKey} and SHA-256. <br/>
+ * This is something like a copy of the {@link RsaSHA256Verifier}.
+ */
+public class OAuth20SHA256Verifier implements Verifier {
+
+ private final PublicKey verificationKey;
+ private final Signature signer;
+
+ /**
+ * Public Constructor.
+ *
+ * @param verificationKey
+ * the key used to verify the signature.
+ */
+ public OAuth20SHA256Verifier(final PublicKey verificationKey) {
+ this.verificationKey = verificationKey;
+
+ try {
+ this.signer = OAuth20SignatureUtil.findSignature(verificationKey).getSignatureInstance();
+ this.signer.initVerify(verificationKey);
+ }
+ catch (InvalidKeyException e) {
+ throw new IllegalStateException("key is invalid", e);
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ catch (NoSuchProviderException e) {
+ throw new IllegalStateException("Cannot get algorithm for the given private key", e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see net.oauth.jsontoken.crypto.Verifier#verifySignature(byte[], byte[])
+ */
+ public void verifySignature(byte[] source, byte[] signature) throws SignatureException {
+ try {
+ signer.initVerify(verificationKey);
+ }
+ catch (InvalidKeyException e) {
+ throw new RuntimeException("key someone become invalid since calling the constructor");
+ }
+ signer.update(source);
+ if (!signer.verify(signature)) {
+ throw new SignatureException("signature did not verify");
+ }
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java
new file mode 100644
index 000000000..78653ceb2
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java
@@ -0,0 +1,94 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import org.apache.commons.lang.StringUtils;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Configuration;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20CertificateErrorException;
+import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.KeyStoreUtils;
+
+public final class OAuth20SignatureUtil {
+
+ private OAuth20SignatureUtil() {
+ throw new InstantiationError();
+ }
+
+ static OAuthSignatureAlgorithm findSignature(final PrivateKey key) {
+ Logger.debug("OAuth - Looking for signature for key " + key.getClass());
+ if (key instanceof RSAPrivateKey) {
+ Logger.debug("OAuth - going to uses SHA256withRSA signature");
+ return OAuthSignatureAlgorithm.RS256;
+ } else if (key instanceof ECPrivateKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature");
+ return OAuthSignatureAlgorithm.ECDSA256;
+ } else if (key instanceof iaik.security.ecc.ecdsa.ECPrivateKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature with iaik");
+ return OAuthSignatureAlgorithm.ECDSA256_IAKIK;
+ } else {
+ throw new IllegalStateException("Cannot find an alorithm for the given private key");
+ }
+ }
+
+ static OAuthSignatureAlgorithm findSignature(final PublicKey key) {
+ if (key instanceof RSAPublicKey) {
+ Logger.debug("OAuth - going to uses SHA256withRSA signature");
+ return OAuthSignatureAlgorithm.RS256;
+ } else if (key instanceof ECPublicKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature");
+ return OAuthSignatureAlgorithm.ECDSA256;
+ } else if (key instanceof iaik.security.ecc.ecdsa.ECPublicKey) {
+ Logger.debug("OAuth - going to uses SHA256withECDSA signature with iaik");
+ return OAuthSignatureAlgorithm.ECDSA256_IAKIK;
+ } else {
+ throw new IllegalStateException("Cannot find an alorithm for the given private key");
+ }
+ }
+
+ public static OAuthSigner loadSigner(String issuer) throws OAuth20Exception {
+ OAuth20Configuration globalConfig = OAuth20Configuration.getInstance();
+
+ if (StringUtils.isEmpty(globalConfig.getJWTKeyStore())) {
+ throw new OAuth20CertificateErrorException("keystore");
+ }
+
+ if (StringUtils.isEmpty(globalConfig.getJWTKeyName())) {
+ throw new OAuth20CertificateErrorException("key name");
+ }
+
+ try {
+ KeyStore ks = KeyStoreUtils.loadKeyStore(globalConfig.getJWTKeyStore(), globalConfig.getJWTKeyStorePassword());
+
+ X509Certificate certificate = (X509Certificate) ks.getCertificate(globalConfig.getJWTKeyName());
+
+ PrivateKey privateKey = (PrivateKey) ks.getKey(globalConfig.getJWTKeyName(), globalConfig.getJWTKeyPassword()
+ .toCharArray());
+ BasicX509Credential credential = new BasicX509Credential();
+ credential.setEntityCertificate(certificate);
+ credential.setPrivateKey(privateKey);
+
+ // Logger.debug("Going to use X509Certificate:");
+ // Logger.debug(certificate);
+ // Logger.debug("Going to use private key:");
+ // Logger.debug(privateKey);
+
+ return new OAuth20SHA256Signer(issuer, globalConfig.getJWTKeyName(), credential.getPrivateKey());
+
+ }
+ catch (Exception e) {
+ Logger.error(e.getMessage(), e);
+ throw new OAuth20CertificateErrorException("keystore");
+ }
+
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java
new file mode 100644
index 000000000..1792ec91e
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthJsonToken.java
@@ -0,0 +1,27 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import net.oauth.jsontoken.JsonToken;
+
+import com.google.gson.JsonObject;
+
+public class OAuthJsonToken extends JsonToken {
+
+ private final OAuthSigner signer;
+
+ public OAuthJsonToken(OAuthSigner signer) {
+ super(signer);
+ this.signer = signer;
+ }
+
+ @Override
+ public JsonObject getHeader() {
+ JsonObject header = new JsonObject();
+ header.addProperty(ALGORITHM_HEADER, signer.getOAuthSignatureAlgorithm().getAlgorithm());
+ String keyId = getKeyId();
+ if (keyId != null) {
+ header.addProperty(KEY_ID_HEADER, keyId);
+ }
+ return header;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java
new file mode 100644
index 000000000..5e023ff35
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSignatureAlgorithm.java
@@ -0,0 +1,62 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Enum of the signature algorithms supported by this package.
+ */
+public enum OAuthSignatureAlgorithm {
+ ECDSA256("SHA256withECDSA", "ECDSA256", null), RS256("SHA256withRSA", "RS256", null), ECDSA256_IAKIK("SHA1withECDSA", "ECDSA256",
+ "IAIK_ECC");
+
+ private final String signatureName;
+ private final String algorithm;
+ private final String providerName;
+
+ private OAuthSignatureAlgorithm(final String signatureName, final String hashAlg, final String providerName) {
+ this.signatureName = signatureName;
+ this.algorithm = hashAlg;
+ this.providerName = providerName;
+ }
+
+ /**
+ * What the signature algorithm is named in the "alg" parameter in a JSON Token's envelope.
+ */
+ public String getAlgorithm() {
+ return this.algorithm;
+ }
+
+ /**
+ *
+ * @return the signature name like SHA256withECDSA or SHA256withRSA
+ */
+ public String getSignatureName() {
+ return this.signatureName;
+ }
+
+ /**
+ * Calls {@link Signature#getInstance(String)} with the defined signature name
+ *
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws NoSuchProviderException
+ */
+ public Signature getSignatureInstance() throws NoSuchAlgorithmException, NoSuchProviderException {
+ if (!StringUtils.isEmpty(this.providerName)) {
+ return Signature.getInstance(this.signatureName, this.providerName);
+ } else {
+ return Signature.getInstance(this.signatureName);
+ }
+ }
+
+ /**
+ * Given the name of the algorithm in the envelope, returns the corresponding enum instance.
+ */
+ public static OAuthSignatureAlgorithm getFromJsonName(String name) {
+ return OAuthSignatureAlgorithm.valueOf(name);
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java
new file mode 100644
index 000000000..265afa7e7
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuthSigner.java
@@ -0,0 +1,7 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.json;
+
+import net.oauth.jsontoken.crypto.Signer;
+
+public interface OAuthSigner extends Signer {
+ public abstract OAuthSignatureAlgorithm getOAuthSignatureAlgorithm();
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20AuthAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java
index 949b06bb2..68f508103 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20AuthAction.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java
@@ -1,4 +1,4 @@
-package at.gv.egovernment.moa.id.protocols.oauth20;
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -8,13 +8,15 @@ 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.moduls.IAction;
import at.gv.egovernment.moa.id.moduls.IRequest;
+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.exceptions.OAuth20Exception;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ResponseTypeException;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ServerErrorException;
-import at.gv.egovernment.moa.id.protocols.oauth20.requests.OAuth20AuthRequest;
import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
import at.gv.egovernment.moa.logging.Logger;
-public class OAuth20AuthAction implements IAction {
+class OAuth20AuthAction implements IAction {
public String processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp,
AuthenticationSession moasession) throws MOAIDException {
@@ -28,37 +30,55 @@ public class OAuth20AuthAction implements IAction {
// oAuthRequest.getTarget());
String responseType = oAuthRequest.getResponseType();
+ AuthenticationSession session = null;
- String code = AuthenticationSessionStoreage.changeSessionID(moasession);
- Logger.debug("Stored session with id: " + code);
- if (responseType.equals(OAuth20Constants.RESPONSE_CODE)) {
+ try {
+ session = AuthenticationSessionStoreage.createSession();
+
+ String code = session.getSessionID();// AuthenticationSessionStoreage.changeSessionID(moasession);
+ Logger.debug("Stored session with id: " + code);
OAuth20SessionObject o = new OAuth20SessionObject();
- o.setScope(oAuthRequest.getScope());
- o.setCode(code);
- moasession.setoAuth20SessionObject(o);
+ if (responseType.equals(OAuth20Constants.RESPONSE_CODE)) {
+ o.setScope(oAuthRequest.getScope());
+ o.setCode(code);
+ o.setAuthDataSession(moasession);
+
+ } else if (responseType.equals(OAuth20Constants.RESPONSE_TOKEN)) {
+ throw new OAuth20ResponseTypeException();
+ }
+
+ // store data in oath session
+ session.setoAuth20SessionObject(o);
+ AuthenticationSessionStoreage.storeSession(session);
+ Logger.debug("Saved OAuth20SessionObject in session with id: " + session.getSessionID());
+
+ // add code and state to redirect url
+ httpResp.setStatus(HttpServletResponse.SC_FOUND);
+ String redirectURI = oAuthRequest.getRedirectUri();
+ String state = oAuthRequest.getState();
+
+ redirectURI = this.addURLParameter(redirectURI, OAuth20Constants.RESPONSE_CODE, code);
+ redirectURI = this.addURLParameter(redirectURI, OAuth20Constants.PARAM_STATE, state);
+
+ String finalUrl = redirectURI;
+ httpResp.addHeader("Location", finalUrl);
+ Logger.debug("REDIRECT TO: " + finalUrl.toString());
+ }
+ catch (Exception e) {
try {
- AuthenticationSessionStoreage.storeSession(moasession);
+ if (session != null) {
+ Logger.debug("Going to destroy session: " + session.getSessionID());
+ AuthenticationSessionStoreage.destroySession(session.getSessionID());
+ }
}
- catch (MOADatabaseException e) {
- throw new OAuth20ServerErrorException();
+ catch (MOADatabaseException e1) {
}
-
- Logger.debug("Saved OAuth20SessionObject in session with id: " + moasession.getSessionID());
- } else if (responseType.equals(OAuth20Constants.RESPONSE_TOKEN)) {
- throw new OAuth20ResponseTypeException();
+ if (e instanceof OAuth20Exception) {
+ throw (OAuth20Exception) e;
+ }
+ throw new OAuth20ServerErrorException();
}
- // add code and state to redirect url
- httpResp.setStatus(HttpServletResponse.SC_FOUND);
- String redirectURI = oAuthRequest.getRedirectUri();
- String state = oAuthRequest.getState();
-
- redirectURI = this.addURLParameter(redirectURI, OAuth20Constants.RESPONSE_CODE, code);
- redirectURI = this.addURLParameter(redirectURI, OAuth20Constants.PARAM_STATE, state);
-
- String finalUrl = redirectURI;
- httpResp.addHeader("Location", finalUrl);
- Logger.debug("REDIRECT TO: " + finalUrl.toString());
return null;
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20AuthRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java
index 8aac75413..eafc56214 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20AuthRequest.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java
@@ -1,4 +1,4 @@
-package at.gv.egovernment.moa.id.protocols.oauth20.requests;
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
import javax.servlet.http.HttpServletRequest;
@@ -12,7 +12,7 @@ import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ResponseTypeException;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParameterException;
-public class OAuth20AuthRequest extends OAuth20BaseRequest {
+class OAuth20AuthRequest extends OAuth20BaseRequest {
private static final long serialVersionUID = 1L;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20BaseRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java
index 05362c977..e6766ddd5 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20BaseRequest.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20BaseRequest.java
@@ -1,4 +1,4 @@
-package at.gv.egovernment.moa.id.protocols.oauth20.requests;
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
import java.util.HashSet;
import java.util.Iterator;
@@ -15,7 +15,6 @@ import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.moduls.RequestImpl;
import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
-import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Protocol;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20InvalidRequestException;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ServerErrorException;
@@ -23,12 +22,16 @@ import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParamet
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.logging.Logger;
-public abstract class OAuth20BaseRequest extends RequestImpl {
+abstract class OAuth20BaseRequest extends RequestImpl {
private static final long serialVersionUID = 1L;
protected Set<String> allowedParameters = new HashSet<String>();
+ protected OAuth20BaseRequest() {
+
+ }
+
protected String getParam(final HttpServletRequest request, final String name, final boolean isNeeded) throws OAuth20Exception {
String param = request.getParameter(name);
Logger.debug("Reading param " + name + " from HttpServletRequest with value " + param);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Protocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java
index 2c8aa8a73..db18b3a3e 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/OAuth20Protocol.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java
@@ -1,4 +1,4 @@
-package at.gv.egovernment.moa.id.protocols.oauth20;
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
import java.net.URLEncoder;
import java.util.HashMap;
@@ -13,8 +13,9 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.moduls.IAction;
import at.gv.egovernment.moa.id.moduls.IModulInfo;
import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
-import at.gv.egovernment.moa.id.protocols.oauth20.requests.OAuth20BaseRequest;
import at.gv.egovernment.moa.logging.Logger;
import com.google.gson.JsonObject;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java
new file mode 100644
index 000000000..b01b2eae7
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenAction.java
@@ -0,0 +1,164 @@
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
+
+import java.security.SignatureException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+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.OAuth20Constants;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20SessionObject;
+import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util;
+import at.gv.egovernment.moa.id.protocols.oauth20.Pair;
+import at.gv.egovernment.moa.id.protocols.oauth20.attributes.OAuth20AttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.oauth20.attributes.OpenIdExpirationTimeAttribute;
+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.json.OAuth20SignatureUtil;
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuthJsonToken;
+import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuthSigner;
+import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
+import at.gv.egovernment.moa.logging.Logger;
+
+import com.google.gson.JsonObject;
+
+class OAuth20TokenAction implements IAction {
+
+ 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: " + session.getSessionID());
+
+ // do checking for different grant types and code
+ if (auth20SessionObject == null || !auth20SessionObject.getCode().equals(oAuthRequest.getCode())) {
+ throw new OAuth20UnauthorizedClientException();
+ } else {
+ Logger.debug("Loaded of OAuth20SessionObject was successful");
+ }
+
+ 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, OpenIdExpirationTimeAttribute.expirationTime);
+
+ // build id token and scope
+ Pair<String, String> pair = buildIdToken(auth20SessionObject.getScope(), oAuthRequest,
+ auth20SessionObject.getAuthDataSession());
+ 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) {
+ Logger.error(e.getMessage(), 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 MOAIDException, SignatureException {
+ OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oAuthRequest.getOAURL());
+ AuthenticationData authData = AuthenticationServer.buildAuthenticationData(session, oaParam, oAuthRequest.getTarget());
+
+ OAuthSigner signer = OAuth20SignatureUtil.loadSigner(authData.getIssuer());
+ OAuthJsonToken token = new OAuthJsonToken(signer);
+
+ StringBuilder resultScopes = new StringBuilder();
+ // always fill with open id
+ OAuth20AttributeBuilder.addScopeOpenId(token.getPayloadAsJsonObject(), session, oaParam, authData);
+ resultScopes.append("openId");
+
+ for (String s : scope.split(" ")) {
+ if (s.equalsIgnoreCase("profile")) {
+ OAuth20AttributeBuilder.addScopeProfile(token.getPayloadAsJsonObject(), session, oaParam, authData);
+ resultScopes.append(" profile");
+ } else if (s.equalsIgnoreCase("eID")) {
+ OAuth20AttributeBuilder.addScopeEID(token.getPayloadAsJsonObject(), session, oaParam, authData);
+ resultScopes.append(" eID");
+ } else if (s.equalsIgnoreCase("eID_gov") && oaParam.getBusinessService()) {
+ OAuth20AttributeBuilder.addScopeEIDGov(token.getPayloadAsJsonObject(), session, oaParam, authData);
+ resultScopes.append(" eID_gov");
+ } else if (s.equalsIgnoreCase("mandate") && session.getUseMandate() && oaParam.getBusinessService()) {
+ OAuth20AttributeBuilder.addScopeMandate(token.getPayloadAsJsonObject(), session, oaParam, authData);
+ resultScopes.append(" mandate");
+ }
+ // 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());
+
+ return Pair.newInstance(token.serializeAndSign(), resultScopes.toString());
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20TokenRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java
index 6d69f8238..99682076d 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/requests/OAuth20TokenRequest.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java
@@ -1,4 +1,4 @@
-package at.gv.egovernment.moa.id.protocols.oauth20.requests;
+package at.gv.egovernment.moa.id.protocols.oauth20.protocol;
import javax.servlet.http.HttpServletRequest;
@@ -11,7 +11,7 @@ import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20InvalidGrantException;
import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParameterException;
-public class OAuth20TokenRequest extends OAuth20BaseRequest {
+class OAuth20TokenRequest extends OAuth20BaseRequest {
private static final long serialVersionUID = 1L;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IAttributeGenerator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IAttributeGenerator.java
new file mode 100644
index 000000000..48502b77b
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IAttributeGenerator.java
@@ -0,0 +1,11 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes;
+
+public interface IAttributeGenerator<ATT> {
+ public abstract ATT buildStringAttribute(final String friendlyName, final String name, final String value);
+
+ public abstract ATT buildIntegerAttribute(final String friendlyName, final String name, final int value);
+
+ public abstract ATT buildLongAttribute(final String friendlyName, final String name, final long value);
+
+ public abstract ATT buildEmptyAttribute(final String friendlyName, final String name);
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IPVPAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IPVPAttributeBuilder.java
new file mode 100644
index 000000000..cf40f96f4
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/IPVPAttributeBuilder.java
@@ -0,0 +1,8 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes;
+
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+
+interface IPVPAttributeBuilder extends PVPConstants, MOAIDAuthConstants, IAttributeBuilder {
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/SamlAttributeGenerator.java
index 4accca580..170c72fb4 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/SamlAttributeGenerator.java
@@ -9,31 +9,26 @@ import org.opensaml.xml.schema.XSString;
import org.opensaml.xml.schema.impl.XSIntegerBuilder;
import org.opensaml.xml.schema.impl.XSStringBuilder;
-import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
-import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
-public abstract class BaseAttributeBuilder implements PVPConstants, MOAIDAuthConstants, IAttributeBuilder {
-
+public class SamlAttributeGenerator implements IAttributeGenerator<Attribute> {
- protected static XMLObject buildAttributeStringValue(String value) {
+ private XMLObject buildAttributeStringValue(String value) {
XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME);
XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
stringValue.setValue(value);
return stringValue;
}
- protected static XMLObject buildAttributeIntegerValue(int value) {
+ private XMLObject buildAttributeIntegerValue(int value) {
XSIntegerBuilder integerBuilder = (XSIntegerBuilder) Configuration.getBuilderFactory().getBuilder(XSInteger.TYPE_NAME);
XSInteger integerValue = integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME);
integerValue.setValue(value);
return integerValue;
}
- protected static Attribute buildStringAttribute(String friendlyName,
- String name, String value) {
- Attribute attribute =
- SAML2Utils.createSAMLObject(Attribute.class);
+ public Attribute buildStringAttribute(final String friendlyName, final String name, final String value) {
+ Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class);
attribute.setFriendlyName(friendlyName);
attribute.setName(name);
attribute.setNameFormat(Attribute.URI_REFERENCE);
@@ -41,10 +36,8 @@ public abstract class BaseAttributeBuilder implements PVPConstants, MOAIDAuthCon
return attribute;
}
- protected static Attribute buildIntegerAttribute(String friendlyName,
- String name, int value) {
- Attribute attribute =
- SAML2Utils.createSAMLObject(Attribute.class);
+ public Attribute buildIntegerAttribute(final String friendlyName, final String name, final int value) {
+ Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class);
attribute.setFriendlyName(friendlyName);
attribute.setName(name);
attribute.setNameFormat(Attribute.URI_REFERENCE);
@@ -52,12 +45,21 @@ public abstract class BaseAttributeBuilder implements PVPConstants, MOAIDAuthCon
return attribute;
}
- protected static Attribute buildemptyAttribute(String friendlyName, String name) {
- Attribute attribute =
- SAML2Utils.createSAMLObject(Attribute.class);
+ public Attribute buildEmptyAttribute(final String friendlyName, final String name) {
+ Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class);
+ attribute.setFriendlyName(friendlyName);
+ attribute.setName(name);
+ attribute.setNameFormat(Attribute.URI_REFERENCE);
+ return attribute;
+ }
+
+ public Attribute buildLongAttribute(String friendlyName, String name, long value) {
+ Attribute attribute = SAML2Utils.createSAMLObject(Attribute.class);
attribute.setFriendlyName(friendlyName);
attribute.setName(name);
attribute.setNameFormat(Attribute.URI_REFERENCE);
+ attribute.getAttributeValues().add(buildAttributeIntegerValue((int) value));
return attribute;
}
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/AttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/AttributeException.java
new file mode 100644
index 000000000..245858ad1
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/AttributeException.java
@@ -0,0 +1,11 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions;
+
+public class AttributeException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public AttributeException(String message) {
+ super(message);
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/InvalidDateFormatAttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/InvalidDateFormatAttributeException.java
new file mode 100644
index 000000000..61540d53f
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/InvalidDateFormatAttributeException.java
@@ -0,0 +1,13 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions;
+
+public class InvalidDateFormatAttributeException extends AttributeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public InvalidDateFormatAttributeException() {
+ super("Date format is invalid.");
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/NoMandateDataAttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/NoMandateDataAttributeException.java
new file mode 100644
index 000000000..7bb09fd85
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/NoMandateDataAttributeException.java
@@ -0,0 +1,10 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions;
+
+public class NoMandateDataAttributeException extends AttributeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public NoMandateDataAttributeException() {
+ super("Mandate data is not available.");
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/UnavailableAttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/UnavailableAttributeException.java
new file mode 100644
index 000000000..df3933774
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/exceptions/UnavailableAttributeException.java
@@ -0,0 +1,18 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions;
+
+public class UnavailableAttributeException extends AttributeException {
+
+ private static final long serialVersionUID = 1L;
+
+ private String attributeName;
+
+ public UnavailableAttributeException(String attributeName) {
+ super("Attribute " + attributeName + " is not available.");
+ this.attributeName = attributeName;
+ }
+
+ public String getAttributeName() {
+ return attributeName;
+ }
+
+}