diff options
Diffstat (limited to 'id/server/idserverlib')
14 files changed, 272 insertions, 96 deletions
diff --git a/id/server/idserverlib/pom.xml b/id/server/idserverlib/pom.xml index e7faf2df6..ba11f949b 100644 --- a/id/server/idserverlib/pom.xml +++ b/id/server/idserverlib/pom.xml @@ -61,6 +61,23 @@ <groupId>MOA.id.server</groupId>
<artifactId>moa-id-commons</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>${hibernate.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-c3p0</artifactId>
+ <version>${hibernate.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ <version>${hibernate.version}</version>
+ </dependency>
+
<!-- <dependency>
<groupId>eu.stork</groupId>
@@ -78,6 +95,7 @@ <artifactId>moa-common</artifactId>
<type>jar</type>
</dependency>
+
<dependency>
<groupId>MOA</groupId>
<artifactId>moa-common</artifactId>
@@ -502,6 +520,12 @@ <artifactId>commons-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${org.apache.commons.lang3.version}</version>
+ </dependency>
+
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java index 3b903009c..587b641c9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java @@ -206,8 +206,8 @@ public class StartAuthentificationParameterParser extends MOAIDAuthConstants{ authURL = authURL.concat(":" + req.getServerPort()); } authURL = authURL.concat(req.getContextPath() + "/"); - - if (!authURL.startsWith("https:")) + + if (!authURL.startsWith("https:") && !AuthConfigurationProviderFactory.getInstance().isHTTPAuthAllowed()) throw new AuthenticationException("auth.07", new Object[] { authURL + "*" }); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java index e4072d0c5..4f321764a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java @@ -145,4 +145,6 @@ public interface AuthConfiguration extends ConfigurationProvider{ */ Map<String, String> getConfigurationWithWildCard(String key); + @Deprecated + public boolean isHTTPAuthAllowed(); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java index 9fc03e2df..f706bb376 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java @@ -1076,4 +1076,14 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide return Arrays.asList(prop.replaceAll(" ", "").split(",")); } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.AuthConfiguration#isHTTPAuthAllowed() + */ + @Override + @Deprecated + public boolean isHTTPAuthAllowed() { + String prop = properties.getProperty("configuration.localhttpallowed.active", "false"); + return Boolean.valueOf(prop); + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java index 71b55d991..25cb952d7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java @@ -50,7 +50,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** - * the AttributeCollector Action tries to get all requested attributes from a set of {@link AttributeProvider} Plugins. + * The AttributeCollector Action tries to get all requested attributes from a set of {@link AttributeProvider} Plugins. * The class is called whenever the {@link AuthenticationRequest} Action is invoked and checks for missing attributes. * Furthermore, the class can handle direct posts. That is when the class triggers an attribute query which needs user * interaction, redirect to another portal, etc. The redirect will hit here and the class can continue to fetch attributes. @@ -80,8 +80,6 @@ public class AttributeCollector implements IAction { } - // TODO extract attribute response and check if it corresponds to the container - if (httpReq.getParameter("SAMLResponse") != null) { Logger.info("Got SAML response from external attribute provider."); @@ -106,7 +104,7 @@ public class AttributeCollector implements IAction { STORKAuthnResponse authnResponse = null; - // check if valid authn request is contained + // check if valid authn response is contained try { authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, httpReq.getRemoteAddr()); } catch (STORKSAMLEngineException ex) { @@ -115,6 +113,22 @@ public class AttributeCollector implements IAction { STORK2Response.setSTORKAuthnResponseToken(decSamlToken); + // check if the attributes are provided for the same person from request + // requires presence of eIdentifier for unambigious correlation + Logger.debug("Checking if the attribute relates to the correct person.."); + try { + String remoteEIdentifier= authnResponse.getPersonalAttributeList().get("eIdentifier").getValue().get(0); + String localEidentifier= container.getResponse().getStorkAuthnResponse().getPersonalAttributeList().get("eIdentifier").getValue().get(0); + if (!remoteEIdentifier.equals(localEidentifier)) { + Logger.error("The attribute is not provided for the same person!"); + throw new MOAIDException("stork.25", null); + } + } catch (NullPointerException ex) { + Logger.warn("Could not check the correlation of attributes from external provider. Ignoring the check."); + //Logger.debug(ex); + //throw new MOAIDException("stork.04", null); // TODO revise message, raise exception when ehvd checked + } + if (authnResponse.getPersonalAttributeList().size() > 0) { Logger.info("Response from external attribute provider contains " + authnResponse.getPersonalAttributeList().size() + " attributes."); container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), authnResponse.getPersonalAttributeList())); @@ -180,9 +194,21 @@ public class AttributeCollector implements IAction { IPersonalAttributeList requestAttributeList = container.getRequest().getPersonalAttributeList(); IPersonalAttributeList responseAttributeList = container.getResponse().getPersonalAttributeList(); List<PersonalAttribute> missingAttributes = new ArrayList<PersonalAttribute>(); + Logger.debug("aquire list of missing attributes"); for (PersonalAttribute current : requestAttributeList) - if (!responseAttributeList.containsKey(current.getName())) - missingAttributes.add(current); + if (!responseAttributeList.containsKey(current.getName())) { + if(null == current.getStatus() || (null != current.getStatus() && !current.getStatus().equals(AttributeStatusType.WITHHELD.value()))) { + // add the ones we need + missingAttributes.add(current); + Logger.debug("add " + current.getName() + " to the list of missing attributes"); + } + } else { + // remove the ones we do not want to share from the response list + if(null != current.getStatus() && current.getStatus().equals(AttributeStatusType.WITHHELD.value())) { + responseAttributeList.remove(current.getName()); + Logger.debug("remove " + current.getName() + " from the list of resulting attributes because the user does not want to disclose the data"); + } + } Logger.info("collecting attributes..."); Logger.debug("found " + missingAttributes.size() + " missing attributes"); @@ -249,10 +275,7 @@ public class AttributeCollector implements IAction { Logger.info("collecting attributes done"); // ask for consent if necessary - if(oaParam.isRequireConsentForStorkAttributes()) - new ConsentEvaluator().requestConsent(container, response, oaParam); - else - new ConsentEvaluator().generateSTORKResponse(response, container); + new ConsentEvaluator().generateSTORKResponse(response, container); return null; // AssertionId // TODO diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java index 48502e9e9..59db5797d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java @@ -163,7 +163,12 @@ public class AuthenticationRequest implements IAction { Logger.debug("Data container prepared"); - return (new AttributeCollector()).processRequest(container, httpReq, httpResp, authData, oaParam); + if(oaParam.isRequireConsentForStorkAttributes()) + new ConsentEvaluator().requestConsent(container, httpReq, httpResp, authData, oaParam); + else + new AttributeCollector().processRequest(container, httpReq, httpResp, authData, oaParam); + + return null; } // // check if we are getting request for citizen of some other country // else if (req instanceof MOASTORKRequest) { @@ -494,11 +499,11 @@ public class AuthenticationRequest implements IAction { Logger.debug("Personal attribute found in request: " + personalAttribute.getName() + " isRequired: " + personalAttribute.isRequired()); moaAttributeProvider.populateAttribute(attributeList, personalAttribute); } catch (Exception e) { - Logger.error("Exception, attributes: " + e.getMessage()); + Logger.error("Exception, attributes: " + e.getMessage(), e); } } } catch (Exception e) { - Logger.error("Exception, attributes: " + e.getMessage()); + Logger.error("Exception, attributes: " + e.getMessage(), e); } Logger.trace("AUTHBLOCK " + authData.getAuthBlock()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java index 9377d045b..30c59af6d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java @@ -23,13 +23,17 @@ package at.gv.egovernment.moa.id.protocols.stork2; import java.io.StringWriter; + +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; + import java.util.ArrayList; import java.util.HashMap; -import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import java.util.Map.Entry; + 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.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; @@ -39,14 +43,13 @@ import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; import eu.stork.peps.auth.commons.PEPSUtil; import eu.stork.peps.auth.commons.PersonalAttribute; -import eu.stork.peps.auth.commons.STORKAuthnResponse; import eu.stork.peps.auth.engine.STORKSAMLEngine; import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType; import eu.stork.peps.exceptions.STORKSAMLEngineException; + import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; -import org.joda.time.DateTime; import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import javax.servlet.http.HttpServletRequest; @@ -72,23 +75,28 @@ public class ConsentEvaluator implements IAction { DataContainer container; try { container = AssertionStorage.getInstance().get(artifactId, DataContainer.class); + req = container.getRequest(); } catch (MOADatabaseException e) { Logger.error("Error fetching incomplete Stork response from temporary storage. Most likely a timeout occured.", e); throw new MOAIDException("stork.17", null); } // evaluate response - for(PersonalAttribute current : container.getResponse().getPersonalAttributeList()) { + for(PersonalAttribute current : container.getRequest().getPersonalAttributeList()) { if(null == httpReq.getParameter(current.getName())) { - current.setStatus(AttributeStatusType.NOT_AVAILABLE.value()); + current.setStatus(AttributeStatusType.WITHHELD.value()); current.setValue(new ArrayList<String>()); current.setComplexValue(new HashMap<String, String>()); } } - // build and send response - generateSTORKResponse(httpResp, container); - + //TODO: CHECK: req.getOAURL() should return the unique OA identifier + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(req.getOAURL()); + if (oaParam == null) + throw new AuthenticationException("stork.12", new Object[]{req.getOAURL()}); + + new AttributeCollector().processRequest(container, httpReq, httpResp, authData, oaParam); + return null; // AssertionId } @@ -96,12 +104,19 @@ public class ConsentEvaluator implements IAction { * Fills the given HttpResponse with the required web page. * * @param container the container + * @param authData * @param response the response * @param oaParam the oa param * @return the string * @throws MOAIDException the mOAID exception */ - public String requestConsent(DataContainer container, HttpServletResponse response, IOAAuthParameters oaParam) throws MOAIDException { + public String requestConsent(DataContainer container, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData, OAAuthParameter oaParam) throws MOAIDException { + //check if we need to collect consent + if(!oaParam.isRequireConsentForStorkAttributes()) { + (new AttributeCollector()).processRequest(container, httpReq, httpResp, authData, oaParam); + return ""; + } + // prepare redirect String newArtifactId; try { @@ -134,15 +149,16 @@ public class ConsentEvaluator implements IAction { // assemble table String table = ""; - for (PersonalAttribute current : container.getResponse().getPersonalAttributeList()) - if ("Available".equals(current.getStatus())) - table += "<tr><td><input type=\"checkbox\" checked=\"yes\" name=\"" + current.getName() + "\"></td><td>" + current.getName() + "</td></tr>\n"; + for (PersonalAttribute current : container.getRequest().getPersonalAttributeList()) + table += "<tr><td><input type=\"checkbox\" checked=\"yes\" name=\"" + current.getName() + "\"></td><td>" + current.getName() + (current.isRequired() ? "" : " (optional)") + "</td></tr>\n"; context.put("tablecontent", table); + for(Entry<String, String> current : oaParam.getFormCustomizaten().entrySet()) + context.put(current.getKey().replace("#", ""), current.getValue()); StringWriter writer = new StringWriter(); template.merge(context, writer); - response.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); + httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); } catch (Exception e) { Logger.error("Velocity error: " + e.getMessage()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java index 3ab4ec4a1..2c7e5b539 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java @@ -26,21 +26,20 @@ import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.data.AuthenticationRole; import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.util.PVPtoSTORKMapper; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import eu.stork.peps.auth.commons.PersonalAttribute; import eu.stork.peps.auth.commons.PersonalAttributeList; import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType; +import org.joda.time.Period; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author bsuzic @@ -55,6 +54,8 @@ public class MOAAttributeProvider { private static final Map<String, String> storkAttributeFunctionMapping; private final MOASTORKRequest moastorkRequest; + // mappings for attribute population methods + // based on mapping of moa authndata and executing functions to extract attributes static { Map<String, String> tempSimpleMap = new HashMap<String, String>(); tempSimpleMap.put("givenName", "getGivenName"); @@ -67,6 +68,9 @@ public class MOAAttributeProvider { tempFunctionMap.put("ECApplicationRole","getECApplicationRole"); tempFunctionMap.put("dateOfBirth", "getFormatedDateOfBirth"); tempFunctionMap.put("MSOrganization", "getMSOrganization"); + tempFunctionMap.put("age", "getAge"); + tempFunctionMap.put("isAgeOver", "getIsAgeOver"); + tempFunctionMap.put("citizenQAALevel", "getQAALevel"); storkAttributeFunctionMapping = Collections.unmodifiableMap(tempFunctionMap); } @@ -79,43 +83,87 @@ public class MOAAttributeProvider { public void populateAttribute(PersonalAttributeList attributeList, PersonalAttribute requestedAttribute ) { String storkAttribute = requestedAttribute.getName(); - if (storkAttributeSimpleMapping.containsKey(storkAttribute)) { + + // TODO: check if authData gets populated with stork attributtes during previous steps; it seems it is not + if (null != authData && null != authData.getStorkAttributes() && authData.getStorkAttributes().containsKey(requestedAttribute.getName())) { + Logger.debug("Trying to get value for attribute directly from STORK2 response [" + storkAttribute + "]"); + try { + PersonalAttribute tmp = authData.getStorkAttributes().get(requestedAttribute.getName()); + attributeList.add((PersonalAttribute) tmp.clone()); + } catch(Exception e) { + Logger.error("Could not retrieve attribute from STORK2 response: " + storkAttribute); + Logger.debug(e); + } + } else if (storkAttributeSimpleMapping.containsKey(storkAttribute)) { Logger.debug("Trying to get value for attribute using simple mapping [" + storkAttribute + "]"); try { Method method = authData.getClass().getDeclaredMethod(storkAttributeSimpleMapping.get(storkAttribute)); - populateAttributeWithMethod(method, authData, attributeList, storkAttribute, requestedAttribute.isRequired()); + populateAttributeWithMethod(method, authData, attributeList, storkAttribute, requestedAttribute); } catch (NoSuchMethodException e) { Logger.error("Could not found MOA extraction method while getting attribute: " + storkAttribute); - e.printStackTrace(); + Logger.debug(e); + } catch (NullPointerException e) { + Logger.error("Error getting MOA extraction method while getting attribute: " + storkAttribute); + Logger.debug(e); } } else if (storkAttributeFunctionMapping.containsKey(storkAttribute)) { Logger.debug("Trying to get value for attribute using function mapping [" + storkAttribute + "]"); try { - Method method = this.getClass().getDeclaredMethod(storkAttributeFunctionMapping.get(storkAttribute)); - populateAttributeWithMethod(method, this, attributeList, storkAttribute, requestedAttribute.isRequired()); + Method method = this.getClass().getDeclaredMethod(storkAttributeFunctionMapping.get(storkAttribute), PersonalAttribute.class); + populateAttributeWithMethod(method, this, attributeList, storkAttribute, requestedAttribute); } catch (NoSuchMethodException e) { Logger.error("Could not found MOA extraction method while getting attribute: " + storkAttribute); - e.printStackTrace(); } } else { Logger.debug("MOA method for extraction of attribute " + storkAttribute + " not defined."); } } - private String geteIdentifier() { + private String getAge(PersonalAttribute personalAttribute) { + if (authData.getDateOfBirth() != null) { + Integer age = new Period(authData.getDateOfBirth().getTime(), Calendar.getInstance().getTime().getTime()).getYears(); + return age >= 0 ? age.toString() : null; + } + return null; // WP4 D4.2, Table 12:age, description - considerations + } + + private String getIsAgeOver(PersonalAttribute personalAttribute) + { + try { + if ((authData.getDateOfBirth() != null) && (personalAttribute.getValue() != null) && (personalAttribute.getValue().size() > 0)) { + Integer ageOver = Integer.parseInt(personalAttribute.getValue().get(0)); + Integer age = new Period(authData.getDateOfBirth().getTime(), Calendar.getInstance().getTime().getTime()).getYears(); + return age >= ageOver ? ageOver.toString() : ""; + } + } catch (Exception ex) { + Logger.error("Error encountered when determining isAgeOver"); + Logger.debug(ex); + } + return null; + } + + public String getQAALevel(PersonalAttribute personalAttribute) { + if (authData.getQAALevel().startsWith(PVPConstants.STORK_QAA_PREFIX)) + return authData.getQAALevel().substring(PVPConstants.STORK_QAA_PREFIX.length()); + else + return null; + } + + + private String geteIdentifier(PersonalAttribute personalAttribute) { Logger.debug("Using base urn for identification value: " + authData.getIdentificationType() + " and target country: " + moastorkRequest.getStorkAuthnRequest().getSpCountry()); try { - return new BPKBuilder().buildStorkeIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(), - moastorkRequest.getStorkAuthnRequest().getSpCountry()); + return new BPKBuilder().buildStorkeIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(), + moastorkRequest.getStorkAuthnRequest().getSpCountry()); } catch (BuildException be) { Logger.error("Stork eid could not be constructed; " + be.getMessage()); return null; // TODO error } } - private List<String> getECApplicationRole() { + private List<String> getECApplicationRole(PersonalAttribute personalAttribute) { List<String> storkRoles = null; if (authData.getAuthenticationRoles() != null @@ -127,29 +175,32 @@ public class MOAAttributeProvider { String storkRole = mapper.map(el); if (MiscUtil.isNotEmpty(storkRole)) storkRoles.add(storkRole); - } } return storkRoles; } - private String getFormatedDateOfBirth() { + private String getFormatedDateOfBirth(PersonalAttribute personalAttribute) { if (authData.getDateOfBirth() != null) { DateFormat fmt = new SimpleDateFormat("yyyyMMdd"); return fmt.format(authData.getDateOfBirth()); } else return null; - } - private void populateAttributeWithMethod(Method method, Object object, PersonalAttributeList attributeList, String storkAttribute, Boolean isRequired) { + private void populateAttributeWithMethod(Method method, Object object, PersonalAttributeList attributeList, String storkAttribute, PersonalAttribute requestedAttribute) { try { - Object attributeValue = method.invoke(object, new Class[]{}); // (Object[]) - + Object attributeValue; + if (storkAttributeSimpleMapping.containsValue(method.getName())) { + attributeValue = method.invoke(object, new Class[]{}); + } else { + attributeValue = method.invoke(object, requestedAttribute); + } + PersonalAttribute newAttribute = new PersonalAttribute(); newAttribute.setName(storkAttribute); - newAttribute.setIsRequired(isRequired); + newAttribute.setIsRequired(requestedAttribute.isRequired()); if (attributeValue != null) { newAttribute.setStatus(AttributeStatusType.AVAILABLE.value()); @@ -182,10 +233,13 @@ public class MOAAttributeProvider { } catch (InvocationTargetException e) { Logger.error("Invocation target exception while getting attribute: " + storkAttribute); - e.printStackTrace(); + Logger.debug(e); } catch (IllegalAccessException e) { Logger.error("Illegal access exception while getting attribute: " + storkAttribute); - e.printStackTrace(); + Logger.debug(e); + } catch (NullPointerException e) { + Logger.error("Could not find method: " + storkAttribute); + Logger.debug(e); } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java index 9207cc2dc..a3fac0f6e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateContainer.java @@ -165,7 +165,8 @@ public abstract class MandateContainer { } public void setPhysicalRepresentativeBirthDate(String physicalRepresentativeBirthDate) { - this.physicalRepresentativeBirthDate = physicalRepresentativeBirthDate; + // making it conform to STORK dateOfBirth specifications, removing dash + this.physicalRepresentativeBirthDate = physicalRepresentativeBirthDate.replaceAll("-",""); } public String getAnnotation() { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java index b48a5acef..e58fe804f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MandateRetrievalRequest.java @@ -41,7 +41,6 @@ import eu.stork.peps.auth.commons.PersonalAttribute; import eu.stork.peps.auth.commons.PersonalAttributeList; import eu.stork.peps.auth.commons.STORKAttrQueryResponse; import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.*; -import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; import javax.servlet.http.HttpServletRequest; @@ -54,14 +53,14 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import java.io.StringWriter; -import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.regex.Pattern; /** - * + * Entry point for mandate retrieval. Processes MIS data and transforms into STORK mandate attribute. + * Additionally provides eIdentifier attribute (if requested) in order to enable identity correlation */ public class MandateRetrievalRequest implements IAction { @@ -78,8 +77,13 @@ public class MandateRetrievalRequest implements IAction { this.QAALevel = translateQAALevel(authData.getQAALevel()); // preparing original content and removing sensitive data from it - this.originalContent = authData.getMISMandate().getMandate(); // TODO ERROR - //Logger.debug("Original content " + StringUtils.newStringUtf8(authData.getMISMandate().getMandate())); + try { + this.originalContent = authData.getMISMandate().getMandate(); + } catch (Exception e) { + Logger.error("Could not extract mandate"); + Logger.debug(e); + throw new MOAIDException("stork.26", new Object[]{}); + } String originalMandate = StringUtils.newStringUtf8(authData.getMISMandate().getMandate()).replaceAll("<pd:Value>.*?==</pd:Value><pd:Type>urn:publicid:gv.at:baseid</pd:Type>","<pd:Value></pd:Value><pd:Type></pd:Type>");; Logger.debug("Removing personal identification value and type from original mandate "); originalContent = StringUtils.getBytesUtf8(originalMandate); @@ -97,13 +101,13 @@ public class MandateRetrievalRequest implements IAction { this.moaStorkRequest = (MOASTORKRequest) req; } else { Logger.error("Internal error - did not receive MOASTORKRequest as expected"); - throw new MOAIDException("stork.16", new Object[]{}); // TODO + throw new MOAIDException("stork.27", new Object[]{}); } if (!(moaStorkRequest.isAttrRequest() || moaStorkRequest.getStorkAttrQueryRequest() == null)) { Logger.error("Did not receive attribute request as expected"); - throw new MOAIDException("stork.16", new Object[]{}); // TODO + throw new MOAIDException("stork.27", new Object[]{}); } MandateContainer mandateContainer = null; @@ -115,7 +119,7 @@ public class MandateRetrievalRequest implements IAction { mandateContainer = new PhyPersonMandateContainer(new String(authData.getMISMandate().getMandate(), "UTF-8")); } catch (Exception ex2) { Logger.error("Could not extract data and create mandate container."); - throw new MOAIDException("stork.16", new Object[]{}); // TODO + throw new MOAIDException("stork.27", new Object[]{}); } } @@ -123,26 +127,21 @@ public class MandateRetrievalRequest implements IAction { IPersonalAttributeList attributeList = new PersonalAttributeList(); + // according to new mapping, only mandate attribute is directly relevant for (PersonalAttribute currentAttribute : sourceAttributeList) { - Logger.debug("Evaluating currentattribute " + currentAttribute.getName()); - if (currentAttribute.getName().equals("mandateContent")) { + Logger.debug("Evaluating attributes, current attribute: " + currentAttribute.getName()); + if (currentAttribute.getName().equals("mandateContent")) { // deprecated MandateContentType mandateContent = getMandateContent(mandateContainer, currentAttribute); attributeList.add(marshallComplexAttribute(currentAttribute, mandateContent)); - } else if (currentAttribute.getName().equals("representative")) { // TODO CHECK IN DETAIL + } else if (currentAttribute.getName().equals("representative")) { // deprecated RepresentationPersonType representative = getRepresentative(mandateContainer, currentAttribute); attributeList.add(marshallComplexAttribute(currentAttribute, representative)); - - //attributeList.add(getRepresentative(mandateContainer, currentAttribute)); } else if (currentAttribute.getName().equals("represented")) { - //attributeList.add(getRepresented(mandateContainer, currentAttribute)); RepresentationPersonType represented = getRepresented(mandateContainer, currentAttribute); attributeList.add(marshallComplexAttribute(currentAttribute, represented)); - } else if (currentAttribute.getName().equals("mandate")) { - //attributeList.add(getMandateType(mandateContainer, currentAttribute)); MandateType mandateType = getMandateType(mandateContainer, currentAttribute); attributeList.add(marshallComplexAttribute(currentAttribute, mandateType)); - } else if (currentAttribute.getName().equals("legalName")) { String legalName = getLegalName(mandateContainer, currentAttribute); if (legalName.length() > 0) { @@ -180,6 +179,11 @@ public class MandateRetrievalRequest implements IAction { } } + if (currentAttribute.getName().equals("eIdentifier")) { + attributeList.add(new PersonalAttribute(currentAttribute.getName(), currentAttribute.isRequired(), Arrays.asList(geteIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(), moaStorkRequest.getStorkAttrQueryRequest().getSpCountry())), AttributeStatusType.AVAILABLE.value())); + Logger.info("Adding eIdentifier for mandate holder using SP country: " + moaStorkRequest.getStorkAttrQueryRequest().getSpCountry()); + } + } @@ -211,7 +215,7 @@ public class MandateRetrievalRequest implements IAction { // ask for consent if necessary if (oaParam.isRequireConsentForStorkAttributes()) - new ConsentEvaluator().requestConsent(container, httpResp, oaParam); + new ConsentEvaluator().requestConsent(container, httpReq, httpResp, authData, oaParam); else new ConsentEvaluator().generateSTORKResponse(httpResp, container); @@ -228,7 +232,7 @@ public class MandateRetrievalRequest implements IAction { if (qaaLevel.equals(PVPConstants.STORK_QAA_1_4)) return 4; Logger.error("Wrong QAA Number format"); - throw new MOAIDException("stork.16", new Object[]{}); + throw new MOAIDException("stork.28", new Object[]{}); } private String geteLPIdentifier(MandateContainer mandateContainer, PersonalAttribute currentAttribute) throws MOAIDException { @@ -237,11 +241,20 @@ public class MandateRetrievalRequest implements IAction { return represented.getELPIdentifier(); } else if (currentAttribute.isRequired()) { Logger.error("Cannot provide eLPIdentifier for natural person."); - throw new MOAIDException("stork.19", new Object[]{currentAttribute.getName()}); // TODO + throw new MOAIDException("stork.29", new Object[]{currentAttribute.getName()}); } return ""; } + private String geteIdentifier(String identificationType, String identificationValue, String destinationCountry) throws MOAIDException { + BPKBuilder bpkBuilder = new BPKBuilder(); + try { + return bpkBuilder.buildStorkeIdentifier(identificationType, identificationValue, destinationCountry); + } catch (BuildException be) { + Logger.error("Could not build STORK eIdentifier while generating mandate assertion."); + throw new MOAIDException("stork.29", new Object[]{}); + } + } private PersonalAttribute marshallComplexAttribute(PersonalAttribute currentAttribute, Object obj) { // TODO refactor StringWriter stringWriter = new StringWriter(); @@ -273,13 +286,22 @@ public class MandateRetrievalRequest implements IAction { private String mapPowersType(MandateContainer mandateContainer) { + Logger.debug("Analyzing mandate of type: " + mandateContainer.getAnnotation() + "."); // using if for java 6 compatibility if necessary if (mandateContainer.getAnnotation().equals("ELGABilateral")) { return "6"; // Health Powers } else if (mandateContainer.getAnnotation().equals("ERsB")) { return "0"; // General Powers + } else if (mandateContainer.getAnnotation().equals("Gesetzliche Vollmacht auf Basis Ergäzungsregister für sonstige Betroffene")) { + return "0"; // General Powers + } else if (mandateContainer.getAnnotation().equals("Gesetzliche Vollmacht auf Basis Ergänzungsregister für sonstige Betroffene")) { + return "0"; // General Powers + } else if (mandateContainer.getAnnotation().contains("Gesetzliche Vollmacht auf Basis Erg")) { + return "0"; // General Powers } else if (mandateContainer.getAnnotation().equals("GeneralvollmachtBilateral")) { return "0"; // General Powers + } else if (mandateContainer.getAnnotation().contains("Gesetzliche Vollmacht auf Basis Firmenbuch")) { + return "0"; // General Powers } else if (mandateContainer.getAnnotation().equals("ERsBMitPostvollmacht")) { return "0"; // General Powers } else if (mandateContainer.getAnnotation().equals("ZVR")) { @@ -301,6 +323,7 @@ public class MandateRetrievalRequest implements IAction { } else if (mandateContainer.getAnnotation().equals("Ziviltechniker")) { return "0"; // General Powers } + Logger.debug("Returning other type of mandate"); return "9"; } @@ -446,7 +469,6 @@ public class MandateRetrievalRequest implements IAction { private String getRepresentedStorkeIdentifier(MandateContainer mandateContainer) throws MOAIDException { - //String identificationType, String identificationValue if (!(mandateContainer instanceof PhyPersonMandateContainer)) { Logger.error("Physical person mandate container missing"); throw new MOAIDException("stork.20", new Object[]{}); // TODO @@ -469,13 +491,7 @@ public class MandateRetrievalRequest implements IAction { throw new MOAIDException("stork.20", new Object[]{}); // TODO } - BPKBuilder bpkBuilder = new BPKBuilder(); - try { - return bpkBuilder.buildStorkeIdentifier(phyPersonMandateContainer.getPhyPersMandatorIdentificationType(), phyPersonMandateContainer.getPhyPersMandatorIdentificationValue(), this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry()); - } catch (BuildException be) { - Logger.error("Could not build STORK eIdentifier while generating mandate assertion."); - throw new MOAIDException("stork.20", new Object[]{}); // TODO - } + return geteIdentifier(phyPersonMandateContainer.getPhyPersMandatorIdentificationType(), phyPersonMandateContainer.getPhyPersMandatorIdentificationValue(), this.moaStorkRequest.getStorkAttrQueryRequest().getSpCountry()); } private String getRepresentingStorkeIdentifier(MandateContainer mandateContainer) throws MOAIDException { @@ -512,6 +528,7 @@ public class MandateRetrievalRequest implements IAction { Logger.error("Could not build STORK eIdentifier while generating mandate assertion."); throw new MOAIDException("stork.20", new Object[]{}); // TODO } + } private RepresentationPersonType getRepresentative(MandateContainer mandateContainer, PersonalAttribute sourceAttribute) throws MOAIDException { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java index ba89663ab..c715b65eb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/PhyPersonMandateContainer.java @@ -109,7 +109,8 @@ public class PhyPersonMandateContainer extends MandateContainer { } public void setPhyPersMandatorBirthDate(String phyPersMandatorBirthDate) { - this.phyPersMandatorBirthDate = phyPersMandatorBirthDate; + // making it conform to STORK dateOfBirth specifications, removing dash + this.phyPersMandatorBirthDate = phyPersMandatorBirthDate.replaceAll("-",""); } public String getPhyPersMandatorIdentificationValue() { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java index f4d963645..f671f0807 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/attributeproviders/MandateAttributeRequestProvider.java @@ -73,6 +73,7 @@ public class MandateAttributeRequestProvider extends AttributeProvider { return "MandateAttributeRequestProvider"; } + // TODO check if used @Override protected IPersonalAttributeList acquire(PersonalAttribute attribute, MOASTORKRequest moastorkRequest, IAuthData authData) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException, MOAIDException { Logger.info("Acquiring attribute: " + attribute.getName() + ", by: " + getAttrProviderName()); @@ -85,10 +86,14 @@ public class MandateAttributeRequestProvider extends AttributeProvider { Logger.info("Attribute " + attribute.getName() + " not supported by the provider: " + getAttrProviderName()); throw new UnsupportedAttributeException(); } - PersonalAttributeList result = new PersonalAttributeList(); - //return result; - + // check if there is eIdentifier included and add if necessary +// if (!requestedAttributes.containsKey("eIdentifier")) { +// PersonalAttribute eIdentifier = new PersonalAttribute(); + // eIdentifier.setName("eIdentifier"); +// eIdentifier.setIsRequired(true); +// requestedAttributes.add(eIdentifier); +// } Logger.info("Thrown external request by: " + getAttrProviderName()); throw new ExternalAttributeRequestRequiredException(this); @@ -111,10 +116,12 @@ public class MandateAttributeRequestProvider extends AttributeProvider { // continue with other attribute providers if there are no attributes current provider is able to handle if (requestedAttributes.size() == 0) { - Logger.info("Attribute(s) " + attributes.toString() + " not supported by the provider: " + getAttrProviderName()); + Logger.info("Attribute(s) " + attributes.toString() + " not supported by the provider: " + getAttrProviderName()); throw new UnsupportedAttributeException(); } + + Logger.info("Thrown external request by: " + getAttrProviderName()); throw new ExternalAttributeRequestRequiredException(this); } @@ -144,7 +151,14 @@ public class MandateAttributeRequestProvider extends AttributeProvider { } - + // TODO ensure that other providers request eidentifier + // check if there is eIdentifier included and add if necessary + if (!requestedAttributes.containsKey("eIdentifier")) { + PersonalAttribute eIdentifier = new PersonalAttribute(); + eIdentifier.setName("eIdentifier"); + eIdentifier.setIsRequired(true); + requestedAttributes.add(eIdentifier); + } //generate AttrQueryRequest STORKAttrQueryRequest attributeRequest = new STORKAttrQueryRequest(); diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 827eeec8d..23a689305 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -234,6 +234,11 @@ stork.21=Der angeforderte QAA-level {0} ist h\u00F6her als der QAA-level der Aut stork.22=Der STORK Authentifizierung erfordert die Auswahl des Herkunftslandes der Betroffenen.
stork.23=Die STORK Authentifizierung f\u00FCr "{0}" wird nicht unterst\u00FCtzt.
stork.24=Die STORK Authentifizierungsantwort enth\uFFFDlt leere Angaben zum Geschlecht.
+stork.25=Die Attribute referenzieren verschiedene Personen.
+stork.26=Fehler bei der Extrahierung von Vollmachtendaten.
+stork.27=Fehler bei der Verarbeitung von STORKRequest.
+stork.28=Fehler bei der Umwandelung von QAA Daten.
+stork.29=Fehler bei der Generierung von STORK-Attribut (eIdentifier/eLPIdentifier)
pvp2.00={0} ist kein gueltiger consumer service index
pvp2.01=Fehler beim kodieren der PVP2 Antwort
diff --git a/id/server/idserverlib/src/main/resources/resources/templates/stork2_consent.html b/id/server/idserverlib/src/main/resources/resources/templates/stork2_consent.html index e21a61665..0ab41f146 100644 --- a/id/server/idserverlib/src/main/resources/resources/templates/stork2_consent.html +++ b/id/server/idserverlib/src/main/resources/resources/templates/stork2_consent.html @@ -80,6 +80,7 @@ overflow:auto; min-width: 190px; height: 260px; + padding: 20px; } h2#tabheader{ @@ -134,6 +135,7 @@ #bkulogin { min-height: 150px; + padding: 20px; } } @@ -146,6 +148,7 @@ #bkulogin { height: 180px; + padding: 20px; } } @@ -175,7 +178,7 @@ color : #000; text-align: center; font-size: 100%; - background-color: #MAIN_BACKGOUNDCOLOR#; + background-color: ${MAIN_BACKGOUNDCOLOR}; } #page { @@ -230,6 +233,7 @@ #bkulogin { min-width: 190px; height: 155px; + padding: 20px; } .setAssertionButton_full { @@ -249,7 +253,7 @@ * { margin: 0; padding: 0; - font-family: #FONTTYPE#; + font-family: ${FONTTYPE}; } #selectArea { @@ -333,13 +337,13 @@ } .hell { - background-color : #MAIN_BACKGOUNDCOLOR#; - color: #MAIN_COLOR#; + background-color : ${MAIN_BACKGOUNDCOLOR}; + color: ${MAIN_COLOR}; } .dunkel { - background-color: #HEADER_BACKGROUNDCOLOR#; - color: #HEADER_COLOR#; + background-color: ${HEADER_BACKGROUNDCOLOR}; + color: ${HEADER_COLOR}; } .main_header { @@ -404,7 +408,7 @@ } </script> -<title>#HEADER_TEXT#</title> +<title>Informationsfreigabe</title> </head> <body onload="onChangeChecks();" onresize="onChangeChecks();"> <div id="page"> @@ -417,7 +421,7 @@ <h2 id="tabheader" class="dunkel" role="heading">STORK Informationsfreigabe</h2> </div> <div id="bkulogin" class="hell" role="form"> - Alle angehakten Daten werden an das fragende Drittland übermittelt. + Wählen Sie jene Daten, die, wenn verfügbar, an ein Drittland weitergegeben werden sollen:</br> <table> ${tablecontent} </table> |