Java tutorial
/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. ******************************************************************************/ /** * */ package at.gv.egovernment.moa.id.auth.stork; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Vector; import javax.activation.DataSource; import javax.xml.transform.Source; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.IOUtils; import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl; import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.exception.ParseException; import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; import at.gv.egovernment.moa.id.client.SZRGWClientException; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DateTimeUtils; import at.gv.egovernment.moa.util.StringUtils; import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse; import eu.stork.oasisdss.api.ApiUtils; import eu.stork.oasisdss.api.LightweightSourceResolver; import eu.stork.oasisdss.api.exceptions.ApiUtilsException; import eu.stork.oasisdss.api.exceptions.UtilsException; import eu.stork.oasisdss.profile.SignResponse; import eu.stork.peps.auth.commons.IPersonalAttributeList; import eu.stork.peps.auth.commons.PersonalAttribute; /** * * Handles all functionality for the processing of a STORK response * @author bzwattendorfer * */ public class STORKResponseProcessor { /** OASIS DSS Namespace */ public static final String OASIS_DSS_NS = "urn:oasis:names:tc:dss:1.0:core:schema"; /** OASIS DSS Success Message */ public static final String OASIS_DSS_SUCCESS_MSG = "urn:oasis:names:tc:dss:1.0:resultmajor:Success"; /** * Checks for attribute. * * @param attributeName the attribute name * @param attributeList the attribute list * @return true, if successful */ public static boolean hasAttribute(String attributeName, IPersonalAttributeList attributeList) { try { getAttributeValue(attributeName, attributeList); return true; } catch (STORKException e) { return false; } } /** * helper for reading attributes. Handles logging and error handling. * * @param attributeName the attribute name * @param attributeList the attribute list * @return the attribute value * @throws STORKException the sTORK exception */ private static String getAttributeValue(String attributeName, IPersonalAttributeList attributeList) throws STORKException { return getAttributeValue(attributeName, attributeList, true); } public static String getAttributeValue(String attributeName, IPersonalAttributeList attributeList, boolean throwException) throws STORKException { try { String result = attributeList.get(attributeName).getValue().get(0); Logger.trace(attributeName + " : " + result); return result; } catch (Exception e) { Logger.error(attributeName + " not found in response"); if (throwException) throw new STORKException(attributeName + " not found in response"); else return null; } } /** * Handels connection to SZR-GW and returns Identity Link on success. * * @param attributeList the attribute list * @param oaFriendlyName the oa friendly name * @param targetType the target type * @param targetValue the target value * @param filters the filters * @param citizenSignature2 * @return Identity Link * @throws STORKException the sTORK exception * @throws MOAIDException */ public static IdentityLink connectToSZRGateway(IPersonalAttributeList attributeList, String oaFriendlyName, String targetType, String targetValue, List<String> filters, String citizenSignature) throws STORKException, MOAIDException { Logger.trace("Calling SZR Gateway with the following attributes:"); CreateIdentityLinkResponse identityLinkResponse = null; IdentityLink identityLink = null; try { Logger.trace("Starting call..."); // if there is no signedDoc attribute, we cannot go on if (citizenSignature == null || citizenSignature.length() == 0) { String signResponseString = getAttributeValue("signedDoc", attributeList); //Extract signature from SIgnResponse Source response1 = new StreamSource(new java.io.StringReader(signResponseString)); SignResponse dssSignResponse = ApiUtils.unmarshal(response1, SignResponse.class); citizenSignature = getCitizienSignatureFromSignResponse(dssSignResponse); } String fiscalNumber = getAttributeValue("fiscalNumber", attributeList, false); // if we have a signedDoc we test for a representation case // - according to stork samlengine and commons if (hasAttribute("mandate", attributeList)) { // we have a representation case String mandate = getAttributeValue("mandate", attributeList, false); if (!hasAttribute("dateOfBirth", attributeList)) { // if we get here, we have a natural person representing a legal person String organizationAddress = getAttributeValue("canonicalRegisteredAddress", attributeList, false); String organizationType = getAttributeValue("translateableType", attributeList, false); identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(citizenSignature, null, null, mandate, organizationAddress, organizationType, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); } else { // if we get here, we have a natural person representing another natural person String eIdentifier = getAttributeValue("eIdentifier", attributeList, false); String givenName = getAttributeValue("givenName", attributeList, false); String lastName = getAttributeValue("surname", attributeList, false); String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false); // gender attribute is mandatory here because of some legal stuff String gender = getAttributeValue("gender", attributeList, false); if (!StringUtils.isEmpty(dateOfBirth)) dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth); identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(eIdentifier, givenName, lastName, dateOfBirth, gender, citizenSignature, null, null, mandate, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); } } // - according to stork spec else if (hasAttribute("mandateContent", attributeList) || hasAttribute("representative", attributeList) || hasAttribute("represented", attributeList)) { // we have a representation case String representative = getAttributeValue("representative", attributeList, false); String represented = getAttributeValue("represented", attributeList, false); String mandate = getAttributeValue("mandateContent", attributeList, false); if (!hasAttribute("dateOfBirth", attributeList)) { // if we get here, we have a natural person representing a legal person String organizationAddress = getAttributeValue("canonicalRegisteredAddress", attributeList, false); String organizationType = getAttributeValue("translateableType", attributeList, false); identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(citizenSignature, representative, represented, mandate, organizationAddress, organizationType, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); } else { // if we get here, we have a natural person representing another natural person String eIdentifier = getAttributeValue("eIdentifier", attributeList, false); String givenName = getAttributeValue("givenName", attributeList, false); String lastName = getAttributeValue("surname", attributeList, false); String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false); // gender attribute is mandatory here because of some legal stuff String gender = getAttributeValue("gender", attributeList, false); if (!StringUtils.isEmpty(dateOfBirth)) dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth); identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(eIdentifier, givenName, lastName, dateOfBirth, gender, citizenSignature, representative, represented, mandate, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); } } else { // we do not have a representation case String eIdentifier = getAttributeValue("eIdentifier", attributeList, false); String givenName = getAttributeValue("givenName", attributeList, false); String lastName = getAttributeValue("surname", attributeList, false); String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false); if (!StringUtils.isEmpty(dateOfBirth)) dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth); identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(eIdentifier, givenName, lastName, dateOfBirth, citizenSignature, fiscalNumber); } if (null != identityLinkResponse.getErrorResponse()) { throw new SZRGWClientException("service.08", (String) identityLinkResponse.getErrorResponse().getErrorCode(), (String) identityLinkResponse.getErrorResponse().getInfo()); } else { IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser( new ByteArrayInputStream(identityLinkResponse.getIdentityLink())); identityLink = ilParser.parseIdentityLink(); Logger.debug("Received Identity Link from SZR Gateway"); //TODO: is this ok? // if (StringUtils.isEmpty(identityLink.getDateOfBirth())) { // identityLink.setDateOfBirth("9999-12-31"); // } } } catch (ParseException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (ApiUtilsException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (IllegalArgumentException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (TransformerConfigurationException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (UtilsException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (TransformerException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (TransformerFactoryConfigurationError e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } catch (IOException e) { Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); throw new MOAIDException("auth.25", null, e); } return identityLink; } /** * Transforms additional STORK attributes to MOA Extended attributes * @param iPersonalAttributeList STORK attribute list * @return */ public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes( IPersonalAttributeList iPersonalAttributeList) { List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>(); if (null == iPersonalAttributeList) return moaExtendedSAMLAttributeList; Logger.trace("Adding the following attributes to MOA assertion: "); int count = 0; for (PersonalAttribute attribute : iPersonalAttributeList) { Object attributeValue = attribute.getValue(); if (null == attributeValue) attributeValue = attribute.getComplexValue(); ExtendedSAMLAttribute extendedSAMLAttribute = new ExtendedSAMLAttributeImpl(attribute.getName(), attributeValue, Constants.STORK_NS_URI, 0); moaExtendedSAMLAttributeList.add(extendedSAMLAttribute); count++; Logger.trace("Additional attribute: " + attribute.getName()); } Logger.debug("Added " + count + " STORK attribute(s) to the MOA assertion."); return moaExtendedSAMLAttributeList; } private static String getCitizienSignatureFromSignResponse(SignResponse dssSignResponse) throws IllegalArgumentException, TransformerConfigurationException, UtilsException, TransformerException, TransformerFactoryConfigurationError, IOException, ApiUtilsException { // fetch signed doc DataSource ds = LightweightSourceResolver.getDataSource(dssSignResponse); if (ds == null) { throw new ApiUtilsException("No datasource found in response"); } InputStream incoming = ds.getInputStream(); String citizenSignature = IOUtils.toString(incoming); incoming.close(); return citizenSignature; } }