From 299c1b3679abecdae88d71002acb626661616b0d Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 19 Feb 2015 12:25:55 +0100 Subject: manuell merge: PEPSConnecterServlet --> PepsConnectorTask --- .../modules/stork/tasks/PepsConnectorTask.java | 269 +++++++++++++++++---- 1 file changed, 217 insertions(+), 52 deletions(-) (limited to 'id/server/modules/module-stork/src/main/java/at/gv') diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java index 94017e9f6..1a18f8198 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java @@ -28,6 +28,8 @@ import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.opensaml.saml2.core.StatusCode; +import org.w3c.dom.Element; +import org.w3c.dom.Node; import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; @@ -36,6 +38,8 @@ import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet; import at.gv.egovernment.moa.id.auth.stork.STORKException; import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor; import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils; @@ -46,9 +50,12 @@ import at.gv.egovernment.moa.id.process.api.ExecutionContext; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; import at.gv.egovernment.moa.id.util.HTTPUtils; +import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.StringUtils; +import at.gv.egovernment.moa.util.XPathUtils; import at.gv.util.xsd.xmldsig.SignatureType; import at.gv.util.xsd.xmldsig.X509DataType; import eu.stork.documentservice.DocumentService; @@ -111,19 +118,9 @@ import eu.stork.peps.exceptions.STORKSAMLEngineException; */ public class PepsConnectorTask extends AbstractAuthServletTask { - private String dtlUrl = null; - public PepsConnectorTask() { super(); - Properties props = new Properties(); - try { - props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties")); - dtlUrl = props.getProperty("docservice.url"); - } catch (IOException e) { - dtlUrl = "http://testvidp.buergerkarte.at/DocumentService/DocumentService"; - Logger.error("Loading DTL config failed, using default value:" + dtlUrl); - e.printStackTrace(); - } + } @Override @@ -235,6 +232,57 @@ public class PepsConnectorTask extends AbstractAuthServletTask { throw new MOAIDException("stork.07", null); } + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moaSession.getPublicOAURLPrefix()); + if (oaParam == null) + throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() }); + + //================== Check QAA level start ==================== + int reqQaa = -1; + int authQaa = -1; + String authQaaStr = null; + try { + reqQaa = storkAuthnRequest.getQaa(); + + //TODO: found better solution, but QAA Level in response could be not supported yet + try { + + authQaaStr = authnResponse.getAssertions().get(0). + getAuthnStatements().get(0).getAuthnContext(). + getAuthnContextClassRef().getAuthnContextClassRef(); + moaSession.setQAALevel(authQaaStr); + + } catch (Throwable e) { + Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level"); + moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel()); + authQaaStr = PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel(); + } + if(authQaaStr != null)//Check value only if set + { + authQaa = Integer.valueOf(authQaaStr.substring(PVPConstants.STORK_QAA_PREFIX.length())); +// authQaa = Integer.valueOf(authQaaStr); + if (reqQaa > authQaa) { + Logger.warn("Requested QAA level does not match to authenticated QAA level"); + throw new MOAIDException("stork.21", new Object[]{reqQaa, authQaa}); + + } + } + } catch (MOAIDException e) { + throw e; + + } catch (Exception e) { + if (Logger.isDebugEnabled()) + Logger.warn("STORK QAA Level evaluation error", e); + + else + Logger.warn("STORK QAA Level evaluation error (ErrorMessage=" + + e.getMessage() + ")"); + + throw new MOAIDException("stork.21", new Object[]{reqQaa, authQaa}); + + } + //================== Check QAA level end ==================== + + Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID); // //////////// incorporate gender from parameters if not in stork response @@ -279,27 +327,42 @@ public class PepsConnectorTask extends AbstractAuthServletTask { new java.io.StringReader(signatureInfo))); // fetch signed doc - DataSource ds = LightweightSourceResolver.getDataSource(dssSignResponse); - if (ds == null) { - throw new ApiUtilsException("No datasource found in response"); + DataSource ds = null; + try{ + ds = LightweightSourceResolver.getDataSource(dssSignResponse); + }catch(Exception e) + { + e.printStackTrace(); } - - InputStream incoming = ds.getInputStream(); - citizenSignature = IOUtils.toString(incoming); - incoming.close(); - - Logger.debug("citizenSignature:" + citizenSignature); - if (isDocumentServiceUsed(citizenSignature) == true) { - Logger.debug("Loading document from DocumentService."); - String url = getDtlUrlFromResponse(dssSignResponse); - // get Transferrequest - String transferRequest = getDocTransferRequest(dssSignResponse.getDocUI(), url); - // Load document from DocujmentService - byte[] data = getDocumentFromDtl(transferRequest, url); - citizenSignature = new String(data, "UTF-8"); - Logger.debug("Overridung citizenSignature with:" + citizenSignature); + if(ds == null){ + //Normal DocumentServices return a http-page, but the SI DocumentService returns HTTP error 500 + //which results in an exception and ds==null + + //try to load document from documentservice + citizenSignature = loadDocumentFromDocumentService(dssSignResponse); + //throw new ApiUtilsException("No datasource found in response"); + } + else + { + InputStream incoming = ds.getInputStream(); + citizenSignature = IOUtils.toString(incoming); + incoming.close(); + + Logger.debug("citizenSignature:"+citizenSignature); + if(isDocumentServiceUsed(citizenSignature)==true) + { + citizenSignature = loadDocumentFromDocumentService(dssSignResponse); + // Logger.debug("Loading document from DocumentService."); + // String url = getDtlUrlFromResponse(dssSignResponse); + // //get Transferrequest + // String transferRequest = getDocTransferRequest(dssSignResponse.getDocUI(), url); + // //Load document from DocumentService + // byte[] data = getDocumentFromDtl(transferRequest, url); + // citizenSignature = new String(data, "UTF-8"); + // Logger.debug("Overridung citizenSignature with:"+citizenSignature); + } } - + JAXBContext ctx = JAXBContext.newInstance(SignatureType.class.getPackage().getName()); SignatureType root = ((JAXBElement) ctx.createUnmarshaller().unmarshal( IOUtils.toInputStream(citizenSignature))).getValue(); @@ -338,11 +401,7 @@ public class PepsConnectorTask extends AbstractAuthServletTask { // Logger.error("could not retrieve moa session"); // throw new AuthenticationException("auth.01", null); // } - OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - moaSession.getPublicOAURLPrefix()); - if (oaParam == null) - throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() }); - + // retrieve target // TODO: check in case of SSO!!! String targetType = null; @@ -361,8 +420,66 @@ public class PepsConnectorTask extends AbstractAuthServletTask { IdentityLink identityLink = null; executionContext.put("identityLinkAvailable", false); try { - identityLink = STORKResponseProcessor.connectToSZRGateway(authnResponse.getPersonalAttributeList(), - oaParam.getFriendlyName(), targetType, null, oaParam.getMandateProfiles(), citizenSignature); + AuthConfigurationProvider config = AuthConfigurationProvider.getInstance(); + if(config.isStorkFakeIdLActive() && config.getStorkFakeIdLCountries().contains(storkAuthnRequest.getCitizenCountryCode())) { + // create fake IdL + // - fetch IdL template from resources + InputStream s = PepsConnectorTask.class.getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml"); + Element idlTemplate = DOMUtils.parseXmlValidating(s); + + identityLink = new IdentityLinkAssertionParser(idlTemplate).parseIdentityLink(); + + // replace data + Element idlassertion = identityLink.getSamlAssertion(); + // - set bpk/wpbk; + Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); + if(!STORKResponseProcessor.hasAttribute("eIdentifier", attributeList)) + throw new STORKException("eIdentifier is missing"); + String eIdentifier = STORKResponseProcessor.getAttributeValue("eIdentifier", attributeList, false); + prIdentification.getFirstChild().setNodeValue(eIdentifier); + + // - set last name + Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH); + if(!STORKResponseProcessor.hasAttribute("surname", attributeList)) + throw new STORKException("surname is missing"); + String familyName = STORKResponseProcessor.getAttributeValue("surname", attributeList, false); + prFamilyName.getFirstChild().setNodeValue(familyName); + + // - set first name + Node prGivenName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); + if(!STORKResponseProcessor.hasAttribute("givenName", attributeList)) + throw new STORKException("givenName is missing"); + String givenName = STORKResponseProcessor.getAttributeValue("givenName", attributeList, false); + prGivenName.getFirstChild().setNodeValue(givenName); + + // - set date of birth + Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); + if(!STORKResponseProcessor.hasAttribute("dateOfBirth", attributeList)) + throw new STORKException("dateOfBirth is missing"); + String dateOfBirth = STORKResponseProcessor.getAttributeValue("dateOfBirth", attributeList, false); + prDateOfBirth.getFirstChild().setNodeValue(dateOfBirth); + + identityLink = new IdentityLinkAssertionParser(idlassertion).parseIdentityLink(); + + //resign IDL + IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance(); + Element resignedilAssertion = identitylinkresigner.resignIdentityLink(identityLink.getSamlAssertion(), config.getStorkFakeIdLResigningKey()); + identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink(); + + } else { + //contact SZR Gateway + Logger.debug("Starting connecting SZR Gateway"); + + identityLink = STORKResponseProcessor.connectToSZRGateway( + authnResponse.getPersonalAttributeList(), + oaParam.getFriendlyName(), + targetType, + null, + oaParam.getMandateProfiles(), + citizenSignature); + + } + } catch (STORKException e) { // this is really nasty but we work against the system here. We are supposed to get the gender attribute // from @@ -422,17 +539,17 @@ public class PepsConnectorTask extends AbstractAuthServletTask { // stork did the authentication step moaSession.setAuthenticated(true); - // TODO: found better solution, but QAA Level in response could be not supported yet - try { - - moaSession.setQAALevel(authnResponse.getAssertions().get(0).getAuthnStatements().get(0) - .getAuthnContext().getAuthnContextClassRef().getAuthnContextClassRef()); - - } catch (Throwable e) { - Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level"); - moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel()); - - } + // TODO: found better solution, but QAA Level in STORK response is not be supported yet +// try { +// +// moaSession.setQAALevel(authnResponse.getAssertions().get(0).getAuthnStatements().get(0) +// .getAuthnContext().getAuthnContextClassRef().getAuthnContextClassRef()); +// +// } catch (Throwable e) { +// Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level"); +// moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel()); +// +// } // session is implicit stored in changeSessionID!!!! String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession); @@ -471,8 +588,12 @@ public class PepsConnectorTask extends AbstractAuthServletTask { private boolean isDocumentServiceUsed(String citizenSignature) // TODo add better check { if (citizenSignature - .contains("
Service Name:{http://stork.eu}DocumentService
Port Name:{http://stork.eu}DocumentServicePort
")) + .contains("
Service Name:{http://stork.eu}DocumentService
Port Name:{http://stork.eu}DocumentServicePort
")) { + Logger.trace("isDocumentServiceUsed => true"); return true; + } + + Logger.trace("isDocumentServiceUsed => false"); return false; } @@ -510,7 +631,9 @@ public class PepsConnectorTask extends AbstractAuthServletTask { private byte[] getDocumentFromDtl(String transferRequest, String eDtlUrl) throws Exception { URL url = null; try { - url = new URL(dtlUrl); + + Logger.trace("getDocumentFromDtl, dtlUrl:'"+getdtlUrl()+"' eDtlUrl:'"+eDtlUrl+"'"); + url = new URL(getdtlUrl()); QName qname = new QName("http://stork.eu", "DocumentService"); Service service = Service.create(url, qname); @@ -520,7 +643,7 @@ public class PepsConnectorTask extends AbstractAuthServletTask { SOAPBinding binding = (SOAPBinding) bp.getBinding(); binding.setMTOMEnabled(true); - if (eDtlUrl.equalsIgnoreCase(dtlUrl)) + if (eDtlUrl.equalsIgnoreCase(getdtlUrl())) return docservice.getDocument(transferRequest, ""); else return docservice.getDocument(transferRequest, eDtlUrl); @@ -541,7 +664,7 @@ public class PepsConnectorTask extends AbstractAuthServletTask { String spCountry = docId.substring(0, docId.indexOf("/")); final STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); STORKAttrQueryRequest req = new STORKAttrQueryRequest(); - req.setAssertionConsumerServiceURL(dtlUrl); + req.setAssertionConsumerServiceURL(getdtlUrl()); req.setDestination(destinationUrl); req.setSpCountry(spCountry); req.setQaa(3);// TODO @@ -562,5 +685,47 @@ public class PepsConnectorTask extends AbstractAuthServletTask { throw new Exception("Error in doc request attribute query generation", e); } } + + private String getdtlUrl() { + String dtlUrl; + try { + AuthConfigurationProvider authConfigurationProvider = AuthConfigurationProvider.getInstance(); + dtlUrl = authConfigurationProvider.getDocumentServiceUrl(); + Logger.info ("PEPSConnectorServlet, using dtlUrl:"+dtlUrl); + + } catch (Exception e) { + dtlUrl = "http://testvidp.buergerkarte.at/DocumentService/DocumentService"; + Logger.error("Loading documentservice url failed, using default value:"+dtlUrl, e); + + } + + +// Properties props = new Properties(); +// try { +// props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties")); +// dtlUrl = props.getProperty("docservice.url"); +// } catch (IOException e) { +// dtlUrl = "http://testvidp.buergerkarte.at/DocumentService/DocumentService"; +// Logger.error("Loading DTL config failed, using default value:" + dtlUrl); +// e.printStackTrace(); +// } + + return dtlUrl; + + } + + private String loadDocumentFromDocumentService(SignResponse dssSignResponse) throws Exception + { + Logger.debug("Loading document from DocumentService."); + String url = getDtlUrlFromResponse(dssSignResponse); + Logger.debug("Loading document from DocumentService, url:"+url); + //get Transferrequest + String transferRequest = getDocTransferRequest(dssSignResponse.getDocUI(), url); + //Load document from DocumentService + byte[] data = getDocumentFromDtl(transferRequest, url); + String citizenSignature = new String(data, "UTF-8"); + Logger.debug("Overridung citizenSignature with:"+citizenSignature); + return citizenSignature; + } } -- cgit v1.2.3