diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv')
30 files changed, 3046 insertions, 280 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index a58f5fce2..a57ab5262 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -29,8 +29,12 @@ import iaik.x509.X509Certificate; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.Principal; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -41,18 +45,24 @@ import java.util.Map; import java.util.Set; import java.util.Vector; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.xpath.XPathAPI; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.xml.util.Base64; +import org.opensaml.xml.util.XMLHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.AuthenticationException; import at.gv.egovernment.moa.id.BuildException; +import at.gv.egovernment.moa.id.MOAIDException; import at.gv.egovernment.moa.id.ParseException; import at.gv.egovernment.moa.id.ServiceException; import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder; @@ -83,6 +93,9 @@ import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser; import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; import at.gv.egovernment.moa.id.auth.servlet.AuthServlet; +import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet; +import at.gv.egovernment.moa.id.auth.stork.STORKAuthnRequestProcessor; +import at.gv.egovernment.moa.id.auth.stork.STORKException; import at.gv.egovernment.moa.id.auth.validator.CreateXMLSignatureResponseValidator; import at.gv.egovernment.moa.id.auth.validator.IdentityLinkValidator; import at.gv.egovernment.moa.id.auth.validator.InfoboxValidator; @@ -90,6 +103,9 @@ import at.gv.egovernment.moa.id.auth.validator.ValidateException; import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidator; import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; import at.gv.egovernment.moa.id.auth.validator.parep.ParepValidator; +import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse; +import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClient; +import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException; import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWConstants; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.ConfigurationProvider; @@ -98,6 +114,8 @@ import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameter; import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameters; +import at.gv.egovernment.moa.id.config.stork.CPEPS; +import at.gv.egovernment.moa.id.config.stork.STORKConfig; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; @@ -113,6 +131,15 @@ import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.DateTimeUtils; import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.StringUtils; +import eu.stork.mw.messages.saml.STORKAuthnRequest; +import eu.stork.vidp.messages.builder.STORKMessagesBuilder; +import eu.stork.vidp.messages.common.STORKConstants; +import eu.stork.vidp.messages.exception.SAMLException; +import eu.stork.vidp.messages.exception.SAMLValidationException; +import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel; +import eu.stork.vidp.messages.stork.RequestedAttributes; +import eu.stork.vidp.messages.util.SAMLUtil; +import eu.stork.vidp.messages.util.XMLUtil; /** * API for MOA ID Authentication Service.<br> {@link AuthenticationSession} is @@ -543,16 +570,16 @@ public class AuthenticationServer implements MOAIDAuthConstants { int b = xmlInfoboxReadResponse.indexOf(se); if (b != -1) { // no identity link found Logger - .info("Es konnte keine Personenbindung auf der Karte gefunden werden. Versuche Anmeldung als ausländische eID."); + .info("Es konnte keine Personenbindung auf der Karte gefunden werden. Versuche Anmeldung als ausl�ndische eID."); return null; } - // spezifikationsgemäßer (SL1.2) Errorcode + // spezifikationsgem��er (SL1.2) Errorcode se = "ErrorCode>4002"; // b = xmlInfoboxReadResponse.contains(se); b = xmlInfoboxReadResponse.indexOf(se); if (b != -1) { // Unbekannter Infoboxbezeichner Logger - .info("Unbekannter Infoboxbezeichner. Versuche Anmeldung als ausländische eID."); + .info("Unbekannter Infoboxbezeichner. Versuche Anmeldung als ausl�ndische eID."); return null; } @@ -1732,7 +1759,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { // builds authentication data and stores it together with a SAML // artifact AuthenticationData authData = buildAuthenticationData(session, vsresp, - useUTC); + useUTC, false); if (session.getUseMandate()) { // mandate mode @@ -2037,17 +2064,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { AuthenticationSession session = getSession(sessionID); // AuthConfigurationProvider authConf = // AuthConfigurationProvider.getInstance(); - try { - String serializedAssertion = DOMUtils.serializeNode(session - .getIdentityLink().getSamlAssertion()); - session.setAuthBlock(serializedAssertion); - } catch (TransformerException e) { - throw new ParseException("parser.04", new Object[] { - REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE }); - } catch (IOException e) { - throw new ParseException("parser.04", new Object[] { - REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE }); - } + // post processing of the infoboxes Iterator iter = session.getInfoboxValidatorIterator(); boolean formpending = false; @@ -2097,7 +2114,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { boolean useCondition = oaParam.getUseCondition(); int conditionLength = oaParam.getConditionLength(); AuthenticationData authData = buildAuthenticationData(session, vsresp, - useUTC); + useUTC, true); String samlAssertion = new AuthenticationDataAssertionBuilder().build( authData, session.getAssertionPrPerson(), session @@ -2141,6 +2158,9 @@ public class AuthenticationServer implements MOAIDAuthConstants { * authentication session * @param verifyXMLSigResp * VerifyXMLSignatureResponse from MOA-SP + * @param useUTC uses correct UTC time format + * @param useUTC indicates that authenticated citizen is a foreigner + * @param isForeigner indicates whether Austrian (false) or foreigner (true) authenticates * @return AuthenticationData object * @throws ConfigurationException * while accessing configuration data @@ -2149,7 +2169,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { */ private AuthenticationData buildAuthenticationData( AuthenticationSession session, - VerifyXMLSignatureResponse verifyXMLSigResp, boolean useUTC) + VerifyXMLSignatureResponse verifyXMLSigResp, boolean useUTC, boolean isForeigner) throws ConfigurationException, BuildException { IdentityLink identityLink = session.getIdentityLink(); @@ -2196,21 +2216,44 @@ public class AuthenticationServer implements MOAIDAuthConstants { } } authData.setSignerCertificate(signerCertificateBase64); - if (businessService) { - authData.setWBPK(identityLink.getIdentificationValue()); + if(!isForeigner) { + //we have Austrian citizen + if (businessService) { + authData.setWBPK(identityLink.getIdentificationValue()); + } else { + authData.setBPK(identityLink.getIdentificationValue()); + + // BZ.., calculation of bPK already before sending AUTHBlock + /* + * if(identityLink.getIdentificationType().equals(Constants. + * URN_PREFIX_BASEID)) { // only compute bPK if online + * application is a public service and we have the Stammzahl + * String bpkBase64 = new BPKBuilder().buildBPK( + * identityLink.getIdentificationValue(), session.getTarget()); + * authData.setBPK(bpkBase64); } + */ + + } } else { - authData.setBPK(identityLink.getIdentificationValue()); - - // BZ.., calculation of bPK already before sending AUTHBlock - /* - * if(identityLink.getIdentificationType().equals(Constants. - * URN_PREFIX_BASEID)) { // only compute bPK if online - * application is a public service and we have the Stammzahl - * String bpkBase64 = new BPKBuilder().buildBPK( - * identityLink.getIdentificationValue(), session.getTarget()); - * authData.setBPK(bpkBase64); } - */ - + //we have foreigner, thus we have to calculate bPK and wbPK now (after receiving identity link from SZR-GW + if (businessService) { + //since we have foreigner, wbPK is not calculated in BKU + if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { + String wbpkBase64 = new BPKBuilder().buildWBPK(identityLink.getIdentificationValue(), session.getDomainIdentifier()); + authData.setWBPK(wbpkBase64); + } + + } else { + + if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { + // only compute bPK if online application is a public service and we have the Stammzahl + String bpkBase64 = new BPKBuilder().buildBPK(identityLink.getIdentificationValue(), session.getTarget()); + authData.setBPK(bpkBase64); + } + + + } + } String ilAssertion = oaParam.getProvideIdentityLink() ? identityLink .getSerializedSamlAssertion() @@ -2227,8 +2270,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { session.setAssertionBusinessService(businessService); session.setAssertionIlAssertion(ilAssertion); session.setAssertionPrPerson(prPerson); - session - .setAssertionSignerCertificateBase64(signerCertificateBase64); + session.setAssertionSignerCertificateBase64(signerCertificateBase64); return authData; @@ -2482,4 +2524,288 @@ public class AuthenticationServer implements MOAIDAuthConstants { return value; } + + /** + * Does the request to the SZR-GW + * @param signature XMLDSIG signature + * @return Identity link assertion + * @throws SZRGWClientException + */ + public CreateIdentityLinkResponse getIdentityLink(String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, Element signature) throws SZRGWClientException { + + SZRGWClient client = new SZRGWClient(); + + try { + AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); + ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter(); + + client.setAddress(connectionParameters.getUrl()); + if (connectionParameters.getUrl().toLowerCase().startsWith("https:")) { + Logger.debug("Initialisiere SSL Verbindung"); + try { + client.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters)); + } catch (IOException e) { + Logger.error("Could not initialize SSL Factory", e); + throw new SZRGWClientException("Could not initialize SSL Factory"); + } catch (GeneralSecurityException e) { + Logger.error("Could not initialize SSL Factory", e); + throw new SZRGWClientException("Could not initialize SSL Factory"); + } catch (PKIException e) { + Logger.error("Could not initialize SSL Factory", e); + throw new SZRGWClientException("Could not initialize SSL Factory"); + } + } + Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")..."); + } + catch (ConfigurationException e) { + Logger.warn(e); + Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null )); + } + + // create request + CreateIdentityLinkResponse response = null; + Element request = null; + try { + Document doc = client.buildGetIdentityLinkRequest(PEPSIdentifier, PEPSFirstname, PEPSFamilyname, PEPSDateOfBirth, signature); + request = doc.getDocumentElement(); + + // send request + response = client.createIdentityLinkResponse(request); + } catch (SZRGWClientException e) { + // give him a second try - Nach dem Starten des Tomcat wird beim ersten Mal das Client-Zertifikat offenbar vom HTTPClient nicht mitgeschickt. + try { + response = client.createIdentityLinkResponse(request); + } + catch (SZRGWClientException e1) { + throw new SZRGWClientException(e1); + } + } + + + return response; + + } + + /** + * Starts a MOA-ID authentication process using STORK + * @param req HttpServletRequest + * @param resp HttpServletResponse + * @param ccc Citizen country code + * @param oaURL URL of the online application + * @param target Target parameter + * @param targetFriendlyName Friendly Name of Target + * @param authURL Authentication URL + * @param sourceID SourceID parameter + * @throws MOAIDException + * @throws AuthenticationException + * @throws WrongParametersException + * @throws ConfigurationException + */ + public static void startSTORKAuthentication( + HttpServletRequest req, + HttpServletResponse resp, + String ccc, + String oaURL, + String target, + String targetFriendlyName, + String authURL, + String sourceID) throws MOAIDException, AuthenticationException, WrongParametersException, ConfigurationException { + + //read configuration paramters of OA + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); + if (oaParam == null) + throw new AuthenticationException("auth.00", new Object[] { oaURL }); + + if (!oaParam.getBusinessService()) { + if (StringUtils.isEmpty(target)) + throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.05"); + } else { + target = null; + } + + //create MOA session + AuthenticationSession moaSession = newSession(); + Logger.info("MOASession " + moaSession.getSessionID() + " angelegt"); + moaSession.setTarget(target); + moaSession.setTargetFriendlyName(targetFriendlyName); + moaSession.setOAURLRequested(oaURL); + moaSession.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); + moaSession.setAuthURL(authURL); + moaSession.setBusinessService(oaParam.getBusinessService()); + moaSession.setDomainIdentifier(oaParam.getIdentityLinkDomainIdentifier()); + if (sourceID != null) + moaSession.setSourceID(sourceID); + + //Start of STORK Processing + STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig(); + + CPEPS cpeps = storkConfig.getCPEPS(ccc); + + Logger.debug("Preparing to assemble STORK AuthnRequest witht the following values:"); + String destination = cpeps.getPepsURL().toExternalForm(); + Logger.debug("C-PEPS URL: " + destination); + + String acsURL = HTTPUtils.getBaseURL(req) + PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN; + Logger.debug("MOA Assertion Consumer URL (PEPSConnctor): " + acsURL); + + String providerName= oaParam.getFriendlyName(); + String issuerValue = HTTPUtils.getBaseURL(req); + Logger.debug("Issuer value: " + issuerValue); + + QualityAuthenticationAssuranceLevel qaaLevel = STORKMessagesBuilder.buildQualityAuthenticationAssuranceLevel(oaParam.getQaaLevel().getValue()); + Logger.debug("QAALevel: " + qaaLevel.getValue()); + + RequestedAttributes requestedAttributes; + + requestedAttributes = oaParam.getRequestedAttributes(); + requestedAttributes.detach(); + List<RequestedAttribute> reqAttributeList = new ArrayList<RequestedAttribute>(); + List<RequestedAttribute> oaReqAttributeList = new ArrayList<RequestedAttribute>(oaParam.getRequestedAttributes().getRequestedAttributes()); + //check if country specific attributes must be additionally requested + if (!cpeps.getCountrySpecificRequestedAttributes().isEmpty()) { + //add country specific attributes to be requested (Hierarchy: default oa attributes > country specific attributes > oa specific attributes + Logger.debug("We have addtional country specific attributes to be requested from the C-PEPS of country: " + ccc); + Logger.debug("The following attributes are requested for this specific country:"); + List<RequestedAttribute> countrySpecificReqAttributeList = new ArrayList<RequestedAttribute>(cpeps.getCountrySpecificRequestedAttributes()); + for (RequestedAttribute csReqAttr : countrySpecificReqAttributeList) { + csReqAttr.detach(); + if (!STORKConstants.DEFAULT_STORK_REQUESTED_ATTRIBUTE_SET.contains(csReqAttr.getName())) { + //this country specific attribute does not override default attribute + if (SAMLUtil.containsAttribute(oaReqAttributeList, csReqAttr.getName())) { + //the same attribute is requested for OA, applying hierachy + //remove oa attribute + oaReqAttributeList.remove(SAMLUtil.getAttribute(oaReqAttributeList, csReqAttr.getName())); + //add country specific attribute instead + Logger.debug("Requested Attribute (" + csReqAttr.getName() + ") is also requested by OA but we use Country Specific value instead"); + } + oaReqAttributeList.add(csReqAttr); + Logger.debug("Country specific requested attribute: " + csReqAttr.getName() + ", isRequired: " + csReqAttr.isRequired()); + } else { + Logger.debug("Country specific requested attribute: " + csReqAttr.getName() + ", isRequired: " + csReqAttr.isRequired() + " tries to overwrite default requested and required attributes, hence we skip it."); + } + + } + reqAttributeList.addAll(oaReqAttributeList); + } else { + //no country specific requested attributes + reqAttributeList.addAll(oaReqAttributeList); + } + + reqAttributeList = (List<RequestedAttribute>) SAMLUtil.releaseDOM(reqAttributeList); + requestedAttributes = STORKMessagesBuilder.buildRequestedAttributes(reqAttributeList); + + if (Logger.isDebugEnabled()) { + Logger.debug("The following attributes are requested for this OA:"); + for (RequestedAttribute logReqAttr : reqAttributeList) { + Logger.debug("OA specific requested attribute: " + logReqAttr.getName() + ", isRequired: " + logReqAttr.isRequired()); + + } + } + + String spSector = StringUtils.isEmpty(target) ? "Business" : target; + String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName(); + String spApplication = spInstitution; + String spCountry = "AT"; + + String textToBeSigned = + CreateXMLSignatureRequestBuilder.buildForeignIDTextToBeSigned("wie im Signaturzertifikat (as in my signature certificate)", oaParam, moaSession); + + //generate AuthnRquest + STORKAuthnRequest storkAuthnRequest = STORKAuthnRequestProcessor.generateSTORKAuthnRequest( + destination, + acsURL, + providerName, + issuerValue, + qaaLevel, + requestedAttributes, + spSector, + spInstitution, + spApplication, + spCountry, + textToBeSigned, + "application/xhtml+xml"); + + Logger.debug("STORK AuthnRequest succesfully assembled."); + + //sign AuthnRequest + String keyStorePath = storkConfig.getSignatureCreationParameter().getKeyStorePath(); + String keyStorePassword = storkConfig.getSignatureCreationParameter().getKeyStorePassword(); + String keyName = storkConfig.getSignatureCreationParameter().getKeyName(); + String keyPassword = storkConfig.getSignatureCreationParameter().getKeyPassword(); + + Logger.debug("Starting signing process of STORK AuthnRequest."); + Logger.trace("Using the following Keystore and Key for that:"); + Logger.trace("KeyStore: " + keyStorePath); + Logger.trace("KeyName: " + keyName); + + try { + storkAuthnRequest = STORKAuthnRequestProcessor.signSTORKAuthnRequest(storkAuthnRequest, keyStorePath, keyStorePassword, keyName, keyPassword); + } catch (SAMLException e) { + Logger.error("Could not sign STORK SAML AuthnRequest.", e); + throw new MOAIDException("stork.00", null); + } + + Logger.info("STORK AuthnRequest successfully signed!"); + + //validate AuthnRequest + try { + STORKAuthnRequestProcessor.validateSTORKAuthnRequest(storkAuthnRequest); + } catch (SAMLValidationException e) { + Logger.error("STORK SAML AuthnRequest not valid.", e); + throw new MOAIDException("stork.01", null); + } + + Logger.debug("STORK AuthnRequest successfully internally validated."); + + //send + moaSession.setStorkAuthnRequest(storkAuthnRequest); + HttpSession httpSession = req.getSession(); + httpSession.setAttribute("MOA-Session-ID", moaSession.getSessionID()); + + Logger.debug("Preparing to send STORK AuthnRequest."); + + try { + STORKAuthnRequestProcessor.sendSTORKAuthnRequest(req, resp, storkAuthnRequest); + } catch (Exception e) { + Logger.error("Error sending STORK SAML AuthnRequest.", e); + httpSession.invalidate(); + throw new MOAIDException("stork.02", new Object[] { destination }); + } + + Logger.info("STORK AuthnRequest successfully sent to: " + storkAuthnRequest.getDestination()); + Logger.debug("STORKAuthnRequest sent (pretty print): "); + Logger.debug(XMLHelper.prettyPrintXML(storkAuthnRequest.getDOM())); + Logger.trace("STORKAuthnRequest sent (original): "); + Logger.trace(XMLUtil.printXML(storkAuthnRequest.getDOM())); + + } + + /** + * Extracts an X509 Certificate out of an XML signagture element + * @param signedXML XML signature element + * @return X509Certificate + * @throws CertificateException + */ + public static X509Certificate getCertificateFromXML(Element signedXML) throws CertificateException { + + NodeList nList = signedXML.getElementsByTagNameNS(Constants.DSIG_NS_URI, "X509Certificate"); + + String base64CertString = XMLUtil.getFirstTextValueFromNodeList(nList); + + if (StringUtils.isEmpty(base64CertString)) { + String msg = "XML does not contain a X509Certificate element."; + Logger.error(msg); + throw new CertificateException(msg); + } + + InputStream is = new ByteArrayInputStream(Base64.decode(base64CertString)); + + CertificateFactory cf; + X509Certificate cert = null; + cf = CertificateFactory.getInstance("X.509"); + cert = (X509Certificate)cf.generateCertificate(is); + + return cert; + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java index f3be98ef0..7d5835f20 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java @@ -47,6 +47,8 @@ public interface MOAIDAuthConstants { public static final String PARAM_SOURCEID = "sourceID"; /** servlet parameter "BKUSelectionTemplate" */ public static final String PARAM_BKUTEMPLATE = "BKUSelectionTemplate"; + /** servlet parameter "CCC (Citizen Country Code)" */ + public static final String PARAM_CCC = "CCC"; /** servlet parameter "BKUSelectionTemplate" */ public static final String PARAM_INPUT_PROCESSOR_SIGN_TEMPLATE = "InputProcessorSignTemplate"; /** default BKU URL */ diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java index b6ba5871d..fa9789530 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java @@ -56,7 +56,7 @@ public class BPKBuilder { target.length() == 0)) { throw new BuildException("builder.00", - new Object[] {"BPK", "Unvollständige Parameterangaben: identificationValue=" + + new Object[] {"BPK", "Unvollständige Parameterangaben: identificationValue=" + identificationValue + ",target=" + target}); } String basisbegriff = identificationValue + "+" + Constants.URN_PREFIX_CDID + "+" + target; @@ -86,7 +86,7 @@ public class BPKBuilder { registerAndOrdNr.length() == 0)) { throw new BuildException("builder.00", - new Object[] {"wbPK", "Unvollständige Parameterangaben: identificationValue=" + + new Object[] {"wbPK", "Unvollständige Parameterangaben: identificationValue=" + identificationValue + ",Register+Registernummer=" + registerAndOrdNr}); } String basisbegriff = identificationValue + "+" + Constants.URN_PREFIX_WBPK + "+" + registerAndOrdNr; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java index 9c696f245..2da7db2b2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java @@ -129,7 +129,31 @@ public class CreateXMLSignatureRequestBuilder implements Constants { * @return String representation of <code><CreateXMLSignatureRequest></code> */ public String buildForeignID(String subject, OAAuthParameter oaParam, AuthenticationSession session) { + + String request = ""; + request += "<sl:CreateXMLSignatureRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">"; + request += "<sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>"; + request += "<sl:DataObjectInfo Structure=\"enveloping\">"; + request += "<sl:DataObject>"; + request += "<sl:XMLContent>"; + + request += buildForeignIDTextToBeSigned(subject, oaParam, session); + request += "</sl:XMLContent>"; + request += "</sl:DataObject>"; + request += "<sl:TransformsInfo>"; + request += "<sl:FinalDataMetaInfo>"; + request += "<sl:MimeType>application/xhtml+xml</sl:MimeType>"; + request += "</sl:FinalDataMetaInfo>"; + request += "</sl:TransformsInfo>"; + request += "</sl:DataObjectInfo>"; + request += "</sl:CreateXMLSignatureRequest>"; + + return request; + } + + public static String buildForeignIDTextToBeSigned(String subject, OAAuthParameter oaParam, AuthenticationSession session) { + String target = session.getTarget(); String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(target); @@ -137,14 +161,9 @@ public class CreateXMLSignatureRequestBuilder implements Constants { String date = DateTimeUtils.buildDate(cal); String time = DateTimeUtils.buildTime(cal); - String request = ""; - request += "<sl:CreateXMLSignatureRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">"; - request += "<sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>"; - request += "<sl:DataObjectInfo Structure=\"enveloping\">"; - request += "<sl:DataObject>"; - request += "<sl:XMLContent>"; - - request += "<html xmlns=\"http://www.w3.org/1999/xhtml\">"; + String request = ""; + request += "<html xmlns=\"http://www.w3.org/1999/xhtml\">"; //application/xhtml+xml text/html + //request += "<meta http-equiv=\"content-type\" content=\"application/xhtml+xml; charset=UTF-8\">"; request += "<head>"; request += "<title>Signatur der Anmeldedaten</title>"; request += "<style type=\"text/css\" media=\"screen\">"; @@ -263,17 +282,9 @@ public class CreateXMLSignatureRequestBuilder implements Constants { request += "</body>"; request += "</html>"; - - request += "</sl:XMLContent>"; - request += "</sl:DataObject>"; - request += "<sl:TransformsInfo>"; - request += "<sl:FinalDataMetaInfo>"; - request += "<sl:MimeType>application/xhtml+xml</sl:MimeType>"; - request += "</sl:FinalDataMetaInfo>"; - request += "</sl:TransformsInfo>"; - request += "</sl:DataObjectInfo>"; - request += "</sl:CreateXMLSignatureRequest>"; - + return request; + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java index 5a18b720b..e861c62fa 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java @@ -24,6 +24,8 @@ package at.gv.egovernment.moa.id.auth.data; + + import iaik.x509.X509Certificate; import java.util.ArrayList; @@ -37,6 +39,7 @@ import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; +import eu.stork.mw.messages.saml.STORKAuthnRequest; /** * Session data to be stored between <code>AuthenticationServer</code> API calls. @@ -204,7 +207,10 @@ public class AuthenticationSession { */ private String pushInfobox; - + /** + * The STORK AuthRequest to be sent to the C-PEPS + */ + private STORKAuthnRequest storkAuthnRequest; /** * Constructor for AuthenticationSession. @@ -814,6 +820,23 @@ public class AuthenticationSession { public void setMandateReferenceValue(String mandateReferenceValue) { this.mandateReferenceValue = mandateReferenceValue; } + + /** + * Gets the STORK SAML AuthnRequest + * @return STORK SAML AuthnRequest + */ + public STORKAuthnRequest getStorkAuthnRequest() { + return storkAuthnRequest; + } + + /** + * Sets the STORK SAML AuthnRequest + * @param storkAuthnRequest STORK SAML AuthnRequest + */ + public void setStorkAuthnRequest(STORKAuthnRequest storkAuthnRequest) { + this.storkAuthnRequest = storkAuthnRequest; + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java index a19618dc2..16041f8cb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java @@ -46,10 +46,18 @@ import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; +import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.WrongParametersException; +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.BoolUtils; import at.gv.egovernment.moa.util.URLDecoder; +import at.gv.egovernment.moa.util.URLEncoder; /** * Base class for MOA-ID Auth Servlets, providing standard error handling @@ -65,7 +73,16 @@ public class AuthServlet extends HttpServlet implements MOAIDAuthConstants { * */ private static final long serialVersionUID = -6929905344382283738L; + + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + Logger.debug("GET " + this.getServletName()); + + this.setNoCachingHeadersInHttpRespone(req, resp); +} /** * Handles an error. <br>> * <ul> @@ -260,4 +277,51 @@ public class AuthServlet extends HttpServlet implements MOAIDAuthConstants { public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); } + + /** + * Set response headers to avoid caching + * @param request HttpServletRequest + * @param response HttpServletResponse + */ + protected void setNoCachingHeadersInHttpRespone(HttpServletRequest request, HttpServletResponse response) { + response.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES); + response.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA); + response.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL); + response.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE); + + } + + /** + * Adds a parameter to a URL. + * @param url the URL + * @param paramname parameter name + * @param paramvalue parameter value + * @return the URL with parameter added + */ + protected static String addURLParameter(String url, String paramname, String paramvalue) { + String param = paramname + "=" + paramvalue; + if (url.indexOf("?") < 0) + return url + "?" + param; + else + return url + "&" + param; + } + + /** + * Checks if HTTP requests are allowed + * @param authURL requestURL + * @throws AuthenticationException if HTTP requests are not allowed + * @throws ConfigurationException + */ + protected void checkIfHTTPisAllowed(String authURL) throws AuthenticationException, ConfigurationException { + // check if HTTP Connection may be allowed (through + // FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY) + String boolStr = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter( + AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY); + if ((!authURL.startsWith("https:")) + && (false == BoolUtils.valueOf(boolStr))) + throw new AuthenticationException("auth.07", + new Object[] { authURL + "*" }); + + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java index 246a47699..bf7a0f714 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java @@ -24,19 +24,17 @@ package at.gv.egovernment.moa.id.auth.servlet;
-import iaik.pki.PKIException; - import java.io.IOException; -import java.security.GeneralSecurityException; +import java.security.cert.CertificateException; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.TransformerException; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.lang.StringEscapeUtils; -import org.w3c.dom.Document; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.MOAIDException; @@ -50,15 +48,10 @@ import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser; import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse; -import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClient; import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException; -import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.ConnectionParameter; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; -import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; import at.gv.egovernment.moa.id.util.ParamValidatorUtils; -import at.gv.egovernment.moa.id.util.SSLUtils; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.URLEncoder; /**
@@ -89,14 +82,7 @@ public class GetForeignIDServlet extends AuthServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- Logger.debug("GET GetForeignIDServlet");
-
- resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
- resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
- resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
- resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
-
-
+ super.doGet(req, resp);
}
/**
@@ -160,10 +146,17 @@ public class GetForeignIDServlet extends AuthServlet { CreateXMLSignatureResponse csresp =
new CreateXMLSignatureResponseParser(xmlCreateXMLSignatureResponse).parseResponseDsig();
- Element signature = csresp.getDsigSignature();
+ Element signature = csresp.getDsigSignature(); + + try { + session.setSignerCertificate(AuthenticationServer.getCertificateFromXML(signature)); + } catch (CertificateException e) { + Logger.error("Could not extract certificate from CreateXMLSignatureResponse"); + throw new MOAIDException("auth.14", null); + }
// make SZR request to the identity link
- CreateIdentityLinkResponse response = getIdentityLink(signature);
+ CreateIdentityLinkResponse response = AuthenticationServer.getInstance().getIdentityLink(null, null, null, null, signature);
if (response.isError()) {
@@ -173,28 +166,30 @@ public class GetForeignIDServlet extends AuthServlet { Element samlAssertion = response.getAssertion();
-// try {
-// System.out.println(DOMUtils.serializeNode(samlAssertion));
-// } catch (TransformerException e) {
-// e.printStackTrace();
-// }
+ try {
+ System.out.println("PB: " + DOMUtils.serializeNode(samlAssertion));
+ } catch (TransformerException e) {
+ e.printStackTrace();
+ }
IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertion);
IdentityLink identitylink = ilParser.parseIdentityLink();
session.setIdentityLink(identitylink);
String samlArtifactBase64 =
- AuthenticationServer.getInstance().getForeignAuthenticationData(sessionID);
- if (!samlArtifactBase64.equals("Redirect to Input Processor")) {
- redirectURL = session.getOAURLRequested();
- if (!session.getBusinessService()) {
- redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(session.getTarget(), "UTF-8"));
- }
- redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
- redirectURL = resp.encodeRedirectURL(redirectURL);
- } else {
- redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, session.getSessionID());
+ AuthenticationServer.getInstance().getForeignAuthenticationData(sessionID); + if (!samlArtifactBase64.equals("Redirect to Input Processor")) { + redirectURL = session.getOAURLRequested(); + if (!session.getBusinessService()) { + redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(session.getTarget(), "UTF-8")); + } + redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8")); + redirectURL = resp.encodeRedirectURL(redirectURL); + + } else { + redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, session.getSessionID()); }
+
resp.setContentType("text/html");
resp.setStatus(302);
resp.addHeader("Location", redirectURL);
@@ -210,84 +205,12 @@ public class GetForeignIDServlet extends AuthServlet { }
}
- /**
- * Adds a parameter to a URL.
- * @param url the URL
- * @param paramname parameter name
- * @param paramvalue parameter value
- * @return the URL with parameter added
- */
- private static String addURLParameter(String url, String paramname, String paramvalue) {
- String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
- /**
- * Does the request to the SZR-GW
- * @param signature XMLDSIG signature
- * @return Identity link assertion
- * @throws SZRGWClientException
- */
- private CreateIdentityLinkResponse getIdentityLink(Element signature) throws SZRGWClientException {
-
- SZRGWClient client = new SZRGWClient();
-
- try {
- AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
- ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter();
-
- client.setAddress(connectionParameters.getUrl());
- if (connectionParameters.getUrl().toLowerCase().startsWith("https:")) {
- Logger.debug("Initialisiere SSL Verbindung");
- try {
- client.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters));
- } catch (IOException e) {
- Logger.error("Could not initialize SSL Factory", e);
- throw new SZRGWClientException("Could not initialize SSL Factory");
- } catch (GeneralSecurityException e) {
- Logger.error("Could not initialize SSL Factory", e);
- throw new SZRGWClientException("Could not initialize SSL Factory");
- } catch (PKIException e) {
- Logger.error("Could not initialize SSL Factory", e);
- throw new SZRGWClientException("Could not initialize SSL Factory");
- }
- }
- Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")...");
- }
- catch (ConfigurationException e) {
- Logger.warn(e);
- Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null ));
- }
-
- // create request
- CreateIdentityLinkResponse response = null;
- Element request = null;
- try {
- Document doc = client.buildGetIdentityLinkRequest(null, null, null, null, signature);
- request = doc.getDocumentElement();
-
- // send request
- response = client.createIdentityLinkResponse(request);
- } catch (SZRGWClientException e) {
- // give him a second try - Nach dem Starten des Tomcat wird beim ersten Mal das Client-Zertifikat offenbar vom HTTPClient nicht mitgeschickt.
- try {
- response = client.createIdentityLinkResponse(request);
- }
- catch (SZRGWClientException e1) {
- throw new SZRGWClientException(e1);
- }
- }
-
-
- return response;
-
- }
+
+
/**
- * Builds the szrgw:GetIdentityLinkRequest für the SZR-GW
+ * Builds the szrgw:GetIdentityLinkRequest f�r the SZR-GW
* @param givenname
* @param familyname
* @param birthday
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java index 9d26ded8a..74b2f80b9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java @@ -206,20 +206,6 @@ public class GetMISSessionIDServlet extends AuthServlet { }
} - /** - * Adds a parameter to a URL. - * @param url the URL - * @param paramname parameter name - * @param paramvalue parameter value - * @return the URL with parameter added - */ - private static String addURLParameter(String url, String paramname, String paramvalue) { - String param = paramname + "=" + paramvalue; - if (url.indexOf("?") < 0) - return url + "?" + param; - else - return url + "&" + param; - }
-
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java new file mode 100644 index 000000000..4ec894d47 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java @@ -0,0 +1,227 @@ +package at.gv.egovernment.moa.id.auth.servlet;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.id.AuthenticationException;
+import at.gv.egovernment.moa.id.MOAIDException;
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.auth.stork.STORKException;
+import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+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.URLEncoder;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
+import eu.stork.mw.messages.saml.STORKResponse;
+import eu.stork.vidp.messages.util.XMLUtil;
+
+/**
+ * Endpoint for receiving STORK response messages
+ */
+public class PEPSConnectorServlet extends AuthServlet {
+ private static final long serialVersionUID = 1L;
+
+ public static final String PEPSCONNECTOR_SERVLET_URL_PATTERN = "/PEPSConnector";
+
+
+ /**
+ * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ super.doGet(request, response);
+ }
+
+ /**
+ * Handles the reception of a STORK response message
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ try {
+
+ Logger.info("PEPSConnector Servlet invoked, expecting C-PEPS message.");
+ Logger.debug("This ACS endpoint is: " + HTTPUtils.getBaseURL(request));
+
+ super.setNoCachingHeadersInHttpRespone(request, response);
+ Logger.trace("No Caching headers set for HTTP response");
+
+ //check if https or only http
+ super.checkIfHTTPisAllowed(request.getRequestURL().toString());
+
+ Logger.debug("Trying to find MOA Session-ID");
+ HttpSession httpSession = request.getSession();
+ String moaSessionID = (String) httpSession.getAttribute("MOA-Session-ID");
+
+ if (StringUtils.isEmpty(moaSessionID)) {
+ //No authentication session has been started before
+ Logger.error("MOA-SessionID was not found, no previous AuthnRequest had been started");
+ throw new AuthenticationException("auth.02", new Object[] { moaSessionID });
+ } else {
+ //We know user and MOA takes over session handling, invalidate HttpSession
+ httpSession.invalidate();
+ }
+
+ Logger.info("Found MOA sessionID: " + moaSessionID);
+
+ Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");
+
+ //extract STORK Response from HTTP Request
+ STORKResponse storkResponse = null;
+ try {
+ storkResponse = STORKResponseProcessor.receiveSTORKRepsonse(request, response);
+ } catch (STORKException e) {
+ Logger.error("Unable to retrieve STORK Response", e);
+ throw new MOAIDException("stork.04", null);
+ }
+
+ Logger.info("STORK SAML Response message succesfully extracted");
+ Logger.debug("STORK response (pretty print): ");
+ Logger.debug(XMLHelper.prettyPrintXML(storkResponse.getDOM()));
+ Logger.trace("STORK response (original): ");
+ Logger.trace(XMLUtil.printXML(storkResponse.getDOM()));
+
+ Logger.debug("Starting validation of SAML response");
+ //verify SAML response
+ try {
+ STORKResponseProcessor.verifySTORKResponse(storkResponse);
+ } catch (STORKException e) {
+ Logger.error("Failed to verify STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ Logger.info("SAML response succesfully verified!");
+
+ String statusCodeValue = storkResponse.getStatus().getStatusCode().getValue();
+
+ if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) {
+ Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue);
+ throw new MOAIDException("stork.06", new Object[] { statusCodeValue });
+ }
+
+ Logger.info("Got SAML response with authentication success message.");
+
+ //check if authentication request was created before
+ AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
+
+ Logger.debug("MOA session is still valid");
+
+ STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();
+
+ if (storkAuthnRequest == null) {
+ Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
+ throw new MOAIDException("stork.07", null);
+ }
+
+ Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
+
+ Logger.debug("Starting validation of SAML assertion");
+ //verify SAML assertion
+ Assertion storkAssertion = storkResponse.getAssertions().get(0);
+ try {
+ STORKResponseProcessor.verifySTORKAssertion(
+ storkAssertion, //assertion
+ request.getRemoteAddr(), //IP address of user
+ storkAuthnRequest.getID(), //ID of STORK AuthnRequest
+ request.getRequestURL().toString(), //destination
+ HTTPUtils.getBaseURL(request), //audience
+ storkAuthnRequest.getRequestedAttributes()); //Requested Attributes
+ } catch (STORKException e) {
+ Logger.error("Failed to verify STORK SAML Assertion", e);
+ throw new MOAIDException("stork.08", null);
+ }
+
+ Logger.info("SAML assertion succesfully verified!");
+
+ Logger.debug("Starting extraction of signedDoc attribute");
+ //extract signed doc element and citizen signature
+ Element citizenSignature = null;
+ try {
+
+ citizenSignature = STORKResponseProcessor.extractCitizenSignature(storkAssertion);
+ moaSession.setAuthBlock(DOMUtils.serializeNode(citizenSignature));
+ moaSession.setSignerCertificate(AuthenticationServer.getCertificateFromXML(citizenSignature));
+
+ } catch (Exception e) {
+ Logger.error("Could not extract citizen signature from C-PEPS", e);
+ throw new MOAIDException("stork.09", null);
+ }
+ Logger.debug("Foregin Citizen signature successfully extracted from STORK Assertion (signedDoc)");
+ Logger.debug("Citizen signature will be verified by SZR Gateway!");
+
+ Logger.debug("Starting connecting SZR Gateway");
+ //contact SZR Gateway
+ IdentityLink identityLink = null;
+ try {
+ identityLink = STORKResponseProcessor.connectToSZRGateway(citizenSignature, storkAssertion.getAttributeStatements().get(0).getAttributes());
+ } catch (STORKException e) {
+ Logger.error("Error connecting SZR Gateway", e);
+ throw new MOAIDException("stork.10", null);
+ }
+ Logger.debug("SZR communication was successfull");
+
+ if (identityLink == null) {
+ Logger.error("SZR Gateway did not return an identity link.");
+ throw new MOAIDException("stork.10", null);
+ }
+ Logger.info("Received Identity Link from SZR Gateway");
+ moaSession.setIdentityLink(identityLink);
+
+ Logger.debug("Adding addtional STORK attributes to MOA assertion");
+ //add other stork attributes to MOA assertion
+ List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(storkAssertion.getAttributeStatements().get(0).getAttributes());
+ moaSession.setExtendedSAMLAttributesOA(moaExtendedSAMLAttibutes);
+
+ //We don't have BKUURL, setting from null to "Not applicable"
+ moaSession.setBkuURL("Not applicable (STORK Authentication)");
+
+ Logger.debug("Starting to assemble MOA assertion");
+ //produce MOA-Assertion and artifact
+ String samlArtifactBase64 =
+ AuthenticationServer.getInstance().getForeignAuthenticationData(moaSessionID);
+ Logger.info("MOA assertion assembled and SAML Artifact generated.");
+
+ //redirect
+ String redirectURL = null;
+ if (!samlArtifactBase64.equals("Redirect to Input Processor")) {
+ redirectURL = moaSession.getOAURLRequested();
+ if (!moaSession.getBusinessService()) {
+ redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(moaSession.getTarget(), "UTF-8"));
+ }
+ redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
+ redirectURL = response.encodeRedirectURL(redirectURL);
+ } else {
+ redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, moaSession.getSessionID());
+ }
+ response.setContentType("text/html");
+ response.setStatus(302);
+ response.addHeader("Location", redirectURL);
+ Logger.info("REDIRECT TO: " + redirectURL);
+
+
+
+ } catch (AuthenticationException e) {
+ handleError(null, e, request, response);
+ } catch (MOAIDException e) {
+ handleError(null, e, request, response);
+ }
+
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java index 355e85ce5..012ed4c14 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java @@ -26,6 +26,7 @@ package at.gv.egovernment.moa.id.auth.servlet; import java.io.IOException; import java.io.PrintWriter; +import java.util.List; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -33,18 +34,29 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringEscapeUtils; +import org.opensaml.saml2.metadata.RequestedAttribute; import at.gv.egovernment.moa.id.AuthenticationException; import at.gv.egovernment.moa.id.MOAIDException; import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.MOAIDAuthInitializer; import at.gv.egovernment.moa.id.auth.WrongParametersException; +import at.gv.egovernment.moa.id.auth.stork.STORKAuthnRequestProcessor; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.stork.CPEPS; +import at.gv.egovernment.moa.id.config.stork.STORKConfig; +import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; import at.gv.egovernment.moa.id.util.ParamValidatorUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.StringUtils; +import eu.stork.mw.messages.saml.STORKAuthnRequest; +import eu.stork.vidp.messages.builder.STORKMessagesBuilder; +import eu.stork.vidp.messages.exception.SAMLException; +import eu.stork.vidp.messages.exception.SAMLValidationException; +import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel; +import eu.stork.vidp.messages.stork.RequestedAttributes; /** * Servlet requested for starting a MOA ID authentication session. @@ -77,7 +89,7 @@ public class StartAuthenticationServlet extends AuthServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - Logger.debug("GET StartAuthentication"); + Logger.debug("GET StartAuthentication"); String authURL = req.getScheme() + "://" + req.getServerName(); if ((req.getScheme().equalsIgnoreCase("https") && req.getServerPort()!=443) || (req.getScheme().equalsIgnoreCase("http") && req.getServerPort()!=80)) { authURL = authURL.concat(":" + req.getServerPort()); @@ -91,6 +103,7 @@ public class StartAuthenticationServlet extends AuthServlet { String templateURL = req.getParameter(PARAM_TEMPLATE); String sessionID = req.getParameter(PARAM_SESSIONID); String useMandate = req.getParameter(PARAM_USEMANDATE); + String ccc = req.getParameter(PARAM_CCC); // escape parameter strings target = StringEscapeUtils.escapeHtml(target); @@ -100,11 +113,9 @@ public class StartAuthenticationServlet extends AuthServlet { templateURL = StringEscapeUtils.escapeHtml(templateURL); sessionID = StringEscapeUtils.escapeHtml(sessionID); useMandate = StringEscapeUtils.escapeHtml(useMandate); + ccc = StringEscapeUtils.escapeHtml(ccc); - resp.setHeader(HEADER_EXPIRES,HEADER_VALUE_EXPIRES); - resp.setHeader(HEADER_PRAGMA,HEADER_VALUE_PRAGMA); - resp.setHeader(HEADER_CACHE_CONTROL,HEADER_VALUE_CACHE_CONTROL); - resp.addHeader(HEADER_CACHE_CONTROL,HEADER_VALUE_CACHE_CONTROL_IE); + setNoCachingHeadersInHttpRespone(req, resp); try { @@ -121,35 +132,56 @@ public class StartAuthenticationServlet extends AuthServlet { throw new WrongParametersException("StartAuthentication", PARAM_USEMANDATE, "auth.12"); if (!ParamValidatorUtils.isValidSourceID(sourceID)) throw new WrongParametersException("StartAuthentication", PARAM_SOURCEID, "auth.12"); + if (!ParamValidatorUtils.isValidCCC(ccc)) + throw new WrongParametersException("StartAuthentication", PARAM_CCC, "auth.12"); + + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); if (oaParam == null) throw new AuthenticationException("auth.00", new Object[] { oaURL }); - + // get target and target friendly name from config String targetConfig = oaParam.getTarget(); - String targetFriendlyNameConfig = oaParam.getTargetFriendlyName(); + String targetFriendlyNameConfig = oaParam.getTargetFriendlyName(); + + String targetFriendlyName = null; + + if (StringUtils.isEmpty(targetConfig)) { + // no target attribut is given in OA config + // target is used from request + // check parameter + if (!ParamValidatorUtils.isValidTarget(target)) + throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.12"); + } else { + // use target from config + target = targetConfig; + targetFriendlyName = targetFriendlyNameConfig; + } + + STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig(); - String getIdentityLinkForm = null; - if (StringUtils.isEmpty(targetConfig)) { - // no target attribut is given in OA config - // target is used from request - // check parameter - if (!ParamValidatorUtils.isValidTarget(target)) - throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.12"); + Logger.info("Starting authentication for a citizen of country: " + (StringUtils.isEmpty(ccc) ? "AT" : ccc)); + // STORK or normal authentication + if (storkConfig.isSTORKAuthentication(ccc)) { + //STORK authentication + Logger.trace("Found C-PEPS configuration for citizen of country: " + ccc); + Logger.debug("Starting STORK authentication"); - getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(authURL, target, null, oaURL, templateURL, bkuURL, useMandate, sessionID, req.getScheme(), sourceID); - } - else { - // use target from config - getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(authURL, targetConfig, targetFriendlyNameConfig, oaURL, templateURL, bkuURL, useMandate, sessionID, req.getScheme(), sourceID); + AuthenticationServer.startSTORKAuthentication(req, resp, ccc, oaURL, target, targetFriendlyName, authURL, sourceID); + + } else { + //normal MOA-ID authentication + Logger.debug("Starting normal MOA-ID authentication"); + + String getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(authURL, target, targetFriendlyName, oaURL, templateURL, bkuURL, useMandate, sessionID, req.getScheme(), sourceID); + + resp.setContentType("text/html;charset=UTF-8"); + PrintWriter out = new PrintWriter(resp.getOutputStream()); + out.print(getIdentityLinkForm); + out.flush(); } - - resp.setContentType("text/html;charset=UTF-8"); - PrintWriter out = new PrintWriter(resp.getOutputStream()); - out.print(getIdentityLinkForm); - out.flush(); Logger.debug("Finished GET StartAuthentication"); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java index f15f839d7..fbf700365 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java @@ -326,19 +326,6 @@ public class VerifyAuthenticationBlockServlet extends AuthServlet { // handleError(null, e, req, resp); // } // } - /** - * Adds a parameter to a URL. - * @param url the URL - * @param paramname parameter name - * @param paramvalue parameter value - * @return the URL with parameter added - */ - private static String addURLParameter(String url, String paramname, String paramvalue) { - String param = paramname + "=" + paramvalue; - if (url.indexOf("?") < 0) - return url + "?" + param; - else - return url + "&" + param; - } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java new file mode 100644 index 000000000..7ffe59fd9 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java @@ -0,0 +1,56 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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.util.List; + +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.metadata.RequestedAttribute; +
+/**
+ * Interface to be implemented for verifying SAML assertions + * + * @author bzwattendorfer
+ *
+ */
+public interface AssertionVerifier {
+ + /** + * Verifies a given assertion + * @param assertion SAML assertion + * @param reqIPAddress IP address of the client + * @param authnRequestID ID of the corresponding authentication request for verification + * @param recipient recipient for verification + * @param audience audience for verification + * @param reqAttrList RequestedAttribute list for verification + * @throws SecurityException + */
+ public void verify(Assertion assertion, String reqIPAddress, String authnRequestID, String recipient, String audience, List<RequestedAttribute> reqAttrList) throws SecurityException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java new file mode 100644 index 000000000..b95ab6218 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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 org.opensaml.xml.security.credential.Credential;
+
+import eu.stork.vidp.messages.exception.SAMLException;
+
+/**
+ * Interface supporting different kinds of Credentials + * + * @author bzwattendorfer
+ *
+ */
+public interface CredentialProvider {
+ + /** + * Gets appropriate credentials + * @return Credential object + * @throws SAMLException + */
+ public Credential getCredential() throws SAMLException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java new file mode 100644 index 000000000..467210b4d --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java @@ -0,0 +1,126 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.x509.BasicX509Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egovernment.moa.util.KeyStoreUtils; +import at.gv.egovernment.moa.util.StringUtils; +import eu.stork.vidp.messages.exception.SAMLException; +
+/** + * Provides credentials from a KeyStore + * @author bzwattendorfer + * + */
+public class KeyStoreCredentialProvider implements CredentialProvider {
+
+ private final static Logger log = LoggerFactory.getLogger(KeyStoreCredentialProvider.class);
+ + /** KeyStore Path */
+ private String keyStorePath;
+ + /** KeyStore Password */
+ private String keyStorePassword;
+ + /** Specific Key Name as Credential */
+ private String keyName;
+ + /** Key password */
+ private String keyPassword;
+
+ /** + * Creates a KeyStoreCredentialProvider object + * @param keyStorePath KeyStore Path + * @param keyStorePassword KeyStore Password + * @param keyName KeyName of the key to be retrieved + * @param keyPassword Password for the Key + */
+ public KeyStoreCredentialProvider(String keyStorePath,
+ String keyStorePassword, String keyName, String keyPassword) {
+ super();
+ this.keyStorePath = keyStorePath;
+ this.keyStorePassword = keyStorePassword;
+ this.keyName = keyName;
+ this.keyPassword = keyPassword;
+ }
+
+ + /** + * Gets the credential object from the KeyStore + */
+ public Credential getCredential() throws SAMLException {
+ log.trace("Retrieving credentials for signing SAML Response.");
+
+ if (StringUtils.isEmpty(this.keyStorePath))
+ throw new SAMLException("No keyStorePath specified");
+ + //KeyStorePassword optional
+ //if (StringUtils.isEmpty(this.keyStorePassword))
+ // throw new SAMLException("No keyStorePassword specified");
+
+ if (StringUtils.isEmpty(this.keyName))
+ throw new SAMLException("No keyName specified");
+ + //KeyStorePassword optional
+ //if (StringUtils.isEmpty(this.keyPassword))
+ // throw new SAMLException("No keyPassword specified");
+
+ KeyStore ks;
+ try {
+ ks = KeyStoreUtils.loadKeyStore(this.keyStorePath, this.keyStorePassword);
+ } catch (Exception e) {
+ log.error("Failed to load keystore information", e);
+ throw new SAMLException(e);
+ }
+
+ //return new KeyStoreX509CredentialAdapter(ks, keyName, keyPwd.toCharArray());
+ BasicX509Credential credential = null;
+ try {
+ java.security.cert.X509Certificate certificate = (X509Certificate) ks.getCertificate(this.keyName);
+ PrivateKey privateKey = (PrivateKey) ks.getKey(this.keyName, this.keyPassword.toCharArray());
+ credential = new BasicX509Credential();
+ credential.setEntityCertificate(certificate);
+ credential.setPrivateKey(privateKey);
+
+ } catch (Exception e) {
+ log.error("Error retrieving signing credentials.", e);
+ throw new SAMLException(e);
+ }
+
+ return credential;
+
+ } + + +}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java new file mode 100644 index 000000000..3048ccbee --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java @@ -0,0 +1,241 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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.util.List; + +import org.joda.time.DateTime; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.Audience; +import org.opensaml.saml2.core.AudienceRestriction; +import org.opensaml.saml2.core.Conditions; +import org.opensaml.saml2.core.SubjectConfirmation; +import org.opensaml.saml2.core.SubjectConfirmationData; +import org.opensaml.saml2.metadata.RequestedAttribute; + +import at.gv.egovernment.moa.logging.Logger; +import eu.stork.vidp.messages.saml.STORKAttribute; +import eu.stork.vidp.messages.util.SAMLUtil; +
+/**
+ * Verifies the SAML assertion according to the STORK specification + * @author bzwattendorfer
+ *
+ */
+public class PEPSConnectorAssertionVerifier implements AssertionVerifier {
+
+ private static final int CLOCK_SKEW_MINUTES = 5; + + private static final boolean IS_USERS_CLIENT_IP_ADDRESS_TO_VERIFY = false;
+
+ /* (non-Javadoc)
+ * @see eu.stork.mw.peps.connector.validation.AssertionVerifier#verifyAssertion(org.opensaml.saml2.core.Assertion, java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void verify(Assertion assertion, String reqIPAddress,
+ String authnRequestID, String recipient, String audience, List<RequestedAttribute> reqAttrList) throws SecurityException {
+
+ //SAML assertion need not to be signed, skipping signature validation
+
+ verifySubjectConfirmation(assertion, reqIPAddress, authnRequestID, recipient); + + Logger.debug("SubjectConfirmationData successfully verified"); +
+ verifyConditions(assertion, audience);
+ + Logger.debug("Conditions successfully verified"); + }
+
+
+ private void verifySubjectConfirmation(Assertion assertion, String reqAddress, String requestID, String recipient) throws SecurityException {
+ for (SubjectConfirmation sc : assertion.getSubject().getSubjectConfirmations()) {
+ verifySubjectConfirmationData(sc.getSubjectConfirmationData(), reqAddress, requestID, recipient);
+ }
+
+ }
+
+ private void verifySubjectConfirmationData(SubjectConfirmationData scData, String reqAddress, String requestID, String recipient) throws SecurityException {
+ //NotBefore not allowed in SSO profile
+ verifyNotOnOrAfter(scData.getNotOnOrAfter()); + + Logger.trace("NotOnOrAfter successfully verified");
+
+ if(IS_USERS_CLIENT_IP_ADDRESS_TO_VERIFY) {
+ verifyClientAddress(scData, reqAddress); + Logger.trace("User's client IP address successfully verified.");
+ } else {
+ Logger.warn("User's client IP address will not be verified.");
+ }
+
+ verifyRecipient(scData, recipient); + Logger.trace("Recipient successfully verified"); +
+ verifyInResponseTo(scData, requestID); + Logger.trace("InResponseTo successfully verified");
+
+ }
+
+ private void verifyNotBefore(DateTime notBefore) throws SecurityException {
+ if (notBefore.minusMinutes(CLOCK_SKEW_MINUTES).isAfterNow()) {
+ String msg = "Subject/Assertion not yet valid, Timestamp: ";
+ Logger.error(msg + notBefore);
+ throw new SecurityException(msg);
+ }
+
+ Logger.trace("Subject/Assertion already valid, notBefore: " + notBefore);
+
+ }
+
+ private void verifyNotOnOrAfter(DateTime notOnOrAfter) throws SecurityException {
+ if (notOnOrAfter.plusMinutes(CLOCK_SKEW_MINUTES).isBeforeNow()) {
+ String msg = "Subject/Assertion no longer valid.";
+ Logger.error(msg);
+ throw new SecurityException(msg);
+ }
+
+ Logger.trace("Subject/Assertion still valid, notOnOrAfter: " + notOnOrAfter);
+ }
+
+ private void verifyClientAddress(SubjectConfirmationData scData, String reqAddress) throws SecurityException {
+ if (!reqAddress.equals(scData.getAddress())) {
+ String msg = "Response coming from wrong Client-Address";
+ Logger.error("Response coming from wrong Client-Address " + reqAddress + ", expected " + scData.getAddress());
+ throw new SecurityException(msg);
+ }
+
+ }
+
+ private void verifyInResponseTo(SubjectConfirmationData scData, String requestID) throws SecurityException {
+ if (!scData.getInResponseTo().equals(requestID)) {
+ String msg = "Assertion issued for wrong request";
+ Logger.error(msg);
+ throw new SecurityException(msg);
+ }
+ }
+
+ private void verifyRecipient(SubjectConfirmationData scData, String reqRecipient) throws SecurityException {
+ if (!scData.getRecipient().equals(reqRecipient)) {
+ String msg = "Assertion intended for another recipient";
+ Logger.error("Assertion intended for recipient " + scData.getRecipient() + "but expected " + reqRecipient);
+ throw new SecurityException(msg);
+ }
+
+ }
+
+ private void verifyAudience(AudienceRestriction audienceRestriction, String reqAudience) throws SecurityException {
+ for (Audience audience : audienceRestriction.getAudiences()) {
+ if (audience.getAudienceURI().equals(reqAudience))
+ return;
+ }
+ String msg = "Assertion sent to wrong audience";
+ Logger.error("Assertion intended for wrong audience, expected " + reqAudience);
+ throw new SecurityException(msg);
+ }
+
+ private void verifyOneTimeUse(String assertionID) {
+ //not necessarily required to check since notBefore and notOnOrAfter are verified
+ //check response Store for already existing assertion
+
+ }
+
+ private void verifyConditions(Assertion assertion, String reqAudience) throws SecurityException {
+ Conditions conditions = assertion.getConditions();
+
+ verifyNotBefore(conditions.getNotBefore()); + Logger.trace("NotBefore successfully verified"); +
+ verifyNotOnOrAfter(conditions.getNotOnOrAfter()); + Logger.trace("NotOnOrAfter successfully verified");
+
+ verifyAudience(conditions.getAudienceRestrictions().get(0), reqAudience); + + Logger.trace("Audience successfully verified");
+
+ } + + public static void validateRequiredAttributes( + List<RequestedAttribute> reqAttrList, + List<Attribute> attrList) + throws STORKException { + + Logger.debug("Starting required attribute validation"); + + if (reqAttrList == null || reqAttrList.isEmpty()) { + Logger.error("Requested Attributes list is empty."); + throw new STORKException("No attributes have been requested"); + } + + if (attrList == null || attrList.isEmpty()) { + Logger.error("STORK AttributeStatement is empty."); + throw new STORKException("No attributes have been received"); + } + + Logger.trace("These attributes have been requested and received: "); + int count = 0; + for (RequestedAttribute reqAttr : reqAttrList) { + Logger.trace("Requested attribute: " + reqAttr.getName() + " isRequired: " + reqAttr.isRequired()); + for(Attribute attr : attrList) { + if (verifyRequestedAttribute(reqAttr, attr)) + count++; + } + } + + int numRequiredReqAttr = getNumberOfRequiredAttributes(reqAttrList); + Logger.trace("Number of requested required attributes: " + numRequiredReqAttr); + Logger.trace("Number of received required attributes: " + count); + + if (count != numRequiredReqAttr) { + Logger.error("Not all required attributes have been received"); + throw new STORKException("Not all required attributes have been received"); + } + Logger.debug("Received all required attributes!"); + + } + + private static boolean verifyRequestedAttribute(RequestedAttribute reqAttr, Attribute attr) { + + if ((reqAttr.getName()).equals(attr.getName())) { + if (reqAttr.isRequired() && SAMLUtil.getStatusFromAttribute(attr).equals(STORKAttribute.ALLOWED_ATTRIBUTE_STATUS_AVAIL)) { + Logger.trace("Received required attribute " + attr.getName() + " status: " + SAMLUtil.getStatusFromAttribute(attr)); + return true; + } + } + return false; + } + + private static int getNumberOfRequiredAttributes(List<RequestedAttribute> reqAttrList) { + int count = 0; + for (RequestedAttribute reqAttr : reqAttrList) + if (reqAttr.isRequired()) count++; + + return count; + } +
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java new file mode 100644 index 000000000..2deeb2aae --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java @@ -0,0 +1,153 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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 org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.BuildException; +import at.gv.egovernment.moa.id.ParseException; +import at.gv.egovernment.moa.id.ServiceException; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.builder.VerifyXMLSignatureRequestBuilder; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; +import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; +import eu.stork.mw.messages.saml.STORKResponse; +import eu.stork.vidp.messages.exception.SAMLValidationException; +import eu.stork.vidp.messages.util.SAMLUtil; +import eu.stork.vidp.messages.util.XMLUtil; +
+/**
+ * Verifies the SMAL response according to the STORK specification + * @author bzwattendorfer
+ *
+ */
+public class PEPSConnectorResponseVerifier implements ResponseVerifier {
+
+
+ /* (non-Javadoc)
+ * @see eu.stork.mw.peps.connector.validation.ResponseVerifier#verify(org.opensaml.saml2.core.Response)
+ */
+ public void verify(STORKResponse response) throws SecurityException {
+
+ verifySignature(response);
+ Logger.debug("Signature of SAML response valid.");
+
+ verifyStandardValidation(response);
+
+ Logger.debug("SAML response format valid.");
+
+ }
+
+
+ private void verifySignature(STORKResponse response) throws SecurityException {
+ //validate Signature
+ try {
+ if (response.isSigned()) { + + String trustProfileID = AuthConfigurationProvider.getInstance().getStorkConfig().getSignatureVerificationParameter().getTrustProfileID(); + + Logger.debug("Invoking MOA-SP with TrustProfileID: " + trustProfileID); +
+ // builds a <VerifyXMLSignatureRequest> for a call of MOA-SP + Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder() + .build(XMLUtil.printXML(response.getDOM()).getBytes(), trustProfileID); + + Logger.trace("VerifyXMLSignatureRequest for MOA-SP succesfully built"); + + Logger.trace("Calling MOA-SP"); + // invokes the call + Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker() + .verifyXMLSignature(domVerifyXMLSignatureRequest); + + // parses the <VerifyXMLSignatureResponse> + VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser( + domVerifyXMLSignatureResponse).parseData(); + + Logger.trace("Received VerifyXMLSignatureResponse from MOA-SP"); + + if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) { + String msg = "Signature of SAMLResponse not valid"; + Logger.error(msg); + throw new SecurityException(msg); + } + + Logger.debug("Signature of SAML response successfully verified"); + + if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) { + String msg = "Certificate of SAMLResponse not valid"; + Logger.error(msg); + throw new SecurityException(msg); + } + + Logger.debug("Signing certificate of SAML response succesfully verified"); +
+ } else {
+ String msg = "SAML Response is not signed.";
+ throw new SecurityException(msg);
+ }
+
+ } catch (ConfigurationException e) {
+ String msg = "Unable to load STORK configuration for STORK SAML Response signature verification.";
+ Logger.error(msg, e);
+ throw new SecurityException(msg, e);
+ } catch (ParseException e) { + String msg = "Unable to parse VerifyXMLSignature Request or Response."; + Logger.error(msg, e); + throw new SecurityException(msg, e); + } catch (BuildException e) { + String msg = "Unable to parse VerifyXMLSignature Request or Response."; + Logger.error(msg, e); + throw new SecurityException(msg, e); + } catch (ServiceException e) { + String msg = "Unable to invoke MOA-SP."; + Logger.error(msg, e); + throw new SecurityException(msg, e); + }
+
+ }
+
+ private void verifyStandardValidation(STORKResponse response) throws SecurityException {
+ try {
+ SAMLUtil.verifySAMLObjectStandardValidation(response, "saml2-core-schema-and-stork-validator");
+ } catch (SAMLValidationException e) {
+ String msg ="SAML Response received not valid.";
+ throw new SecurityException(msg, e);
+ }
+
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java new file mode 100644 index 000000000..848937824 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java @@ -0,0 +1,44 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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 eu.stork.mw.messages.saml.STORKResponse; + +/** + * Interface to be implemented for SAML response verification + * @author bzwattendorfer + * + */
+public interface ResponseVerifier {
+ + /** + * Verifies a STORK response + * @param response STORK response + * @throws SecurityException + */
+ public void verify(STORKResponse response) throws SecurityException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java new file mode 100644 index 000000000..ff30919bc --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java @@ -0,0 +1,170 @@ +/**
+ *
+ */
+package at.gv.egovernment.moa.id.auth.stork;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.app.VelocityEngine;
+import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.Endpoint;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
+import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
+import org.opensaml.xml.security.credential.Credential;
+
+import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
+import eu.stork.vidp.messages.builder.STORKMessagesBuilder;
+import eu.stork.vidp.messages.exception.SAMLException;
+import eu.stork.vidp.messages.exception.SAMLValidationException;
+import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel;
+import eu.stork.vidp.messages.stork.RequestedAttributes;
+import eu.stork.vidp.messages.util.SAMLUtil;
+
+/**
+ * Class handling all necessary functionality for STORK AuthnRequest processing
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class STORKAuthnRequestProcessor {
+
+ /**
+ * Creates a STORK AuthnRequest
+ * @param destination Destination URL
+ * @param acsURL Assertion Consumer Service URL
+ * @param providerName SP Provider Name
+ * @param issuerValue Issuer Name
+ * @param qaaLevel STORK QAALevel to be requested
+ * @param requestedAttributes Requested Attributes to be requested
+ * @param spSector Sp Sector
+ * @param spInstitution SP Institution
+ * @param spApplication SP Application
+ * @param spCountry SP Country
+ * @param textToBeSigned text to be included in signedDoc element
+ * @param mimeType mimeType for the text to be signed in signedDoc
+ * @return STORK AuthnRequest
+ */
+ public static STORKAuthnRequest generateSTORKAuthnRequest(
+ String destination,
+ String acsURL,
+ String providerName,
+ String issuerValue,
+ QualityAuthenticationAssuranceLevel qaaLevel,
+ RequestedAttributes requestedAttributes,
+ String spSector,
+ String spInstitution,
+ String spApplication,
+ String spCountry,
+ String textToBeSigned,
+ String mimeType) {
+
+
+ STORKAuthnRequest storkAuthnRequest =
+ STORKMessagesBuilder.buildSTORKAuthnRequest(
+ destination,
+ acsURL,
+ providerName,
+ issuerValue,
+ qaaLevel,
+ requestedAttributes,
+ spSector,
+ spInstitution,
+ spApplication,
+ spCountry);
+
+ STORKMessagesBuilder.buildAndAddSignatureRequestToAuthnRequest(storkAuthnRequest, textToBeSigned, mimeType, true);
+
+ Logger.debug("Added signedDoc attribute to STORK AuthnRequest");
+
+ return storkAuthnRequest;
+
+ }
+
+ /**
+ * Signs a STORK AuthnRequest
+ * @param storkAuthnRequest STORK AuthRequest to sign
+ * @param keyStorePath KeyStorePath to the signing key
+ * @param keyStorePassword KeyStore Password
+ * @param keyName Signing key name
+ * @param keyPassword Signing key password
+ * @return Signed STORK AuthnRequest
+ * @throws SAMLException
+ */
+ public static STORKAuthnRequest signSTORKAuthnRequest(
+ STORKAuthnRequest storkAuthnRequest,
+ String keyStorePath,
+ String keyStorePassword,
+ String keyName,
+ String keyPassword) throws SAMLException {
+
+ Logger.trace("Building Credential Provider for signing process");
+
+ CredentialProvider credentialProvider = new KeyStoreCredentialProvider(keyStorePath, keyStorePassword, keyName, keyPassword);
+
+ Credential credential = credentialProvider.getCredential();
+
+ Logger.trace("Credentials found");
+
+ SAMLUtil.signSAMLObject(storkAuthnRequest, credential);
+
+ return storkAuthnRequest;
+ }
+
+ /**
+ * Validates a STORK AuthnRequest
+ * @param storkAuthnRequest STORK AuthnRequest to validate
+ * @throws SAMLValidationException
+ */
+ public static void validateSTORKAuthnRequest(STORKAuthnRequest storkAuthnRequest) throws SAMLValidationException {
+
+ SAMLUtil.verifySAMLObjectStandardValidation(storkAuthnRequest, "saml2-core-schema-and-stork-validator");
+
+ }
+
+ /**
+ * Sends a STORK AuthnRequest (Endpoint taken out of AuthnRequest)
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @param storkAuthnRequest STORK AuthnRequest to send
+ * @throws Exception
+ */
+ public static void sendSTORKAuthnRequest(HttpServletRequest request, HttpServletResponse response, STORKAuthnRequest storkAuthnRequest) throws Exception {
+
+ Logger.trace("Create endpoint...");
+ Endpoint endpoint = STORKMessagesBuilder.buildSAMLObject(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
+ endpoint.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
+ endpoint.setLocation(storkAuthnRequest.getDestination());
+
+
+ Logger.trace("Prepare SAMLMessageContext...");
+ HTTPOutTransport outTransport = new HttpServletResponseAdapter(response, request.isSecure());
+ BasicSAMLMessageContext<?, STORKAuthnRequest, ?> samlMessageContext = new BasicSAMLMessageContext();
+ samlMessageContext.setOutboundMessageTransport(outTransport);
+ samlMessageContext.setPeerEntityEndpoint(endpoint);
+
+ Logger.trace("Set STORK SAML AuthnRequest to SAMLMessageContext...");
+ samlMessageContext.setOutboundSAMLMessage(storkAuthnRequest);
+
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+
+// HTTPPostEncoder encoder = new HTTPPostEncoder(velocityEngine, "/templates/saml2-post-binding.vm");
+ HTTPPostEncoder encoder = new HTTPPostEncoder(velocityEngine, "/saml2-post-binding-moa.vm");
+
+ Logger.trace("HTTP-Post encode SAMLMessageContext...");
+ encoder.encode(samlMessageContext);
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java new file mode 100644 index 000000000..5b737603b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java @@ -0,0 +1,42 @@ +/**
+ *
+ */
+package at.gv.egovernment.moa.id.auth.stork;
+
+
+/**
+ * Exception thrown if error occurs in STORK processing
+ * @author bzwattendorfer
+ *
+ */
+public class STORKException extends Exception{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public STORKException() {
+ super();
+
+ }
+
+ public STORKException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+ public STORKException(String message) {
+ super(message);
+
+ }
+
+ public STORKException(Throwable cause) {
+ super(cause);
+
+ }
+
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java new file mode 100644 index 000000000..c98ca87b9 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java @@ -0,0 +1,405 @@ +/**
+ *
+ */
+package at.gv.egovernment.moa.id.auth.stork;
+
+import iaik.x509.X509Certificate;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.List;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
+
+import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml2.metadata.SurName;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
+import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
+import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.id.ParseException;
+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.parser.IdentityLinkAssertionParser;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.mw.messages.saml.STORKResponse;
+import eu.stork.vidp.messages.common.STORKConstants;
+import eu.stork.vidp.messages.util.SAMLUtil;
+import eu.stork.vidp.messages.util.XMLUtil;
+
+/**
+ *
+ * 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";
+
+ /**
+ * Extracts a STORK response from a HTTP message
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @return STORK Response
+ * @throws STORKException
+ */
+ public static STORKResponse receiveSTORKRepsonse(HttpServletRequest request, HttpServletResponse response) throws STORKException {
+
+ HTTPInTransport httpInTransport = new HttpServletRequestAdapter(request);
+ HTTPOutTransport httpOutTransport = new HttpServletResponseAdapter(response, request.isSecure());
+
+ httpInTransport.getPeerAddress();
+
+ String samlResponseString = request.getParameter("SAMLResponse");
+
+ if (StringUtils.isEmpty(samlResponseString)) {
+ Logger.error("SAMLResponse not found in request.");
+ throw new STORKException("SAMLResponse not found in request.");
+ }
+
+ BasicSAMLMessageContext samlMessageContext = new BasicSAMLMessageContext();
+
+ samlMessageContext.setInboundMessageTransport(httpInTransport);
+ samlMessageContext.setOutboundMessageTransport(httpOutTransport);
+
+ HTTPPostDecoder postDecoder = new HTTPPostDecoder();
+
+ try {
+ postDecoder.decode(samlMessageContext);
+ } catch (Exception e) {
+ Logger.error("Error decoding SAMLResponse message", e);
+ throw new STORKException("Error decoding SAMLResponse message", e);
+ }
+
+ if (!(samlMessageContext.getInboundSAMLMessage() instanceof STORKResponse)) {
+ Logger.error("Message received is not a SAMLResponse message");
+ throw new STORKException("Message received is not a SAMLResponse message");
+ }
+
+ STORKResponse samlResponse = (STORKResponse) samlMessageContext.getInboundSAMLMessage();
+
+ return samlResponse;
+ }
+
+ /**
+ * Verifies a STORK response according STORK specification
+ * @param storkResponse STORK Response to verify
+ * @throws STORKException if validation fails
+ */
+ public static void verifySTORKResponse(STORKResponse storkResponse) throws STORKException {
+
+ ResponseVerifier responseVerifier = new PEPSConnectorResponseVerifier();
+ try {
+ responseVerifier.verify(storkResponse);
+ } catch (SecurityException e) {
+ Logger.error("Error validating response message from PEPS.", e);
+ throw new STORKException("Error validating response message from PEPS.");
+ }
+
+ }
+
+ /**
+ * Verifies a STORK assertion
+ * @param assertion STORK assertion
+ * @param ipAddress Client IP address
+ * @param authnRequestID ID of the AuthnRequest
+ * @param recipient recipient for verification
+ * @param audience audience for verification
+ * @param reqAttributeList RequestedAttribute list for verification
+ * @throws STORKException
+ */
+ public static void verifySTORKAssertion(
+ Assertion assertion,
+ String ipAddress,
+ String authnRequestID,
+ String recipient,
+ String audience,
+ List<RequestedAttribute> reqAttributeList) throws STORKException {
+
+ //validate Assertion
+ AssertionVerifier assertionVerifier = new PEPSConnectorAssertionVerifier();
+ try {
+ assertionVerifier.verify(assertion, ipAddress, authnRequestID, recipient, audience, reqAttributeList);
+
+ //verify if all required attributes are present
+ PEPSConnectorAssertionVerifier.validateRequiredAttributes(reqAttributeList, assertion.getAttributeStatements().get(0).getAttributes());
+
+ } catch (SecurityException e) {
+ Logger.error("Error verifying assertion from PEPS", e);
+ throw new STORKException("Error validating assertion received from PEPS.");
+ }
+
+ }
+
+ /**
+ * Extracts the citizen signature from the signedDoc element present in the STORK assertion
+ * @param storkAssertion STORK assertion
+ * @return citizen signature as XML
+ * @throws STORKException
+ */
+ public static Element extractCitizenSignature(Assertion storkAssertion) throws STORKException {
+
+ Logger.debug("Processing DSS signature response from PEPS");
+
+ Element signatureResponse = getSignedDocAttributeValue(storkAssertion);
+
+ if (signatureResponse == null) {
+ String msg = "Could not find DSS signature response in SAML assertion";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.debug("Found DSS signature in SAML assertion");
+
+ Logger.debug("DSS Signature creation response received from PEPS (pretty print):");
+ Logger.debug(XMLHelper.prettyPrintXML(signatureResponse));
+ Logger.trace("DSS Signature creation response received from PEPS (original):");
+ Logger.trace(XMLUtil.printXML(signatureResponse));
+
+ Element signature = getSignature(signatureResponse);
+
+ if (signature == null) {
+ String msg = "Could not find citizen signature in SAML assertion";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.debug("Found foreign citizen signature in SAML assertion (pretty print):");
+ Logger.debug(XMLHelper.prettyPrintXML(signature));
+ Logger.trace("Found foreign citizen signature in SAML assertion (original):");
+ Logger.trace(XMLUtil.printXML(signature));
+
+ return signature;
+ }
+
+ /**
+ * Extracts the signedDoc attribute from a STORK assertion as XML
+ * @param storkAssertion STORK assertion
+ * @return Value of signedDoc attribute
+ * @throws STORKException
+ */
+ private static Element getSignedDocAttributeValue(Assertion storkAssertion) throws STORKException {
+
+ XMLObject xmlObj = SAMLUtil.getAttributeValue(storkAssertion.getAttributeStatements().get(0).getAttributes(), STORKConstants.STORK_ATTRIBUTE_SIGNEDDOC);
+
+
+ if (xmlObj instanceof XSAny)
+ return getSignedDocAttributeValueFromAny((XSAny) xmlObj);
+ else if (xmlObj instanceof XSString)
+ return getSignedDocAttributValueFromString((XSString) xmlObj);
+ else
+ return null;
+
+ }
+
+ /**
+ * Get signedDoc as XML if provided as anyType
+ * @param any AttributeValue as anyType
+ * @return signedDoc as XML
+ */
+ private static Element getSignedDocAttributeValueFromAny(XSAny any) {
+ if (!any.getUnknownXMLObjects(new QName(OASIS_DSS_NS, "SignResponse")).isEmpty()) {
+ XMLObject xmlObj = any.getUnknownXMLObjects(new QName(OASIS_DSS_NS, "SignResponse")).get(0);
+ return xmlObj.getDOM();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get signedDoc as XML if provided as String
+ * @param string AttributeValue as String
+ * @return signedDoc as XML
+ * @throws STORKException
+ */
+ private static Element getSignedDocAttributValueFromString(XSString string) throws STORKException {
+ try {
+ return XMLUtil.stringToDOM(string.getValue());
+ } catch (Exception e) {
+ Logger.error("Error building DOM", e);
+ throw new STORKException(e);
+
+ }
+ }
+
+ /**
+ * Extracts the signature value out of a DSS response
+ * @param signatureResponse DSS signature response
+ * @return signature
+ * @throws STORKException
+ */
+ private static Element getSignature(Element signatureResponse) throws STORKException {
+
+ NodeList nList = signatureResponse.getElementsByTagNameNS(OASIS_DSS_NS, "ResultMajor");
+
+ String resultMajor = XMLUtil.getFirstTextValueFromNodeList(nList);
+
+ if (StringUtils.isEmpty(resultMajor)) {
+ String msg = "DSS response not correct, ResultMajor element missing.";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.trace("ResultMajor of DSS response: " + resultMajor);
+
+ if (!OASIS_DSS_SUCCESS_MSG.equals(resultMajor)) {
+ String msg = "DSS response not correct, ResultMajor is " + resultMajor;
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ NodeList nList2 = signatureResponse.getElementsByTagNameNS(OASIS_DSS_NS, "Base64Signature");;
+
+ String base64SigString = XMLUtil.getFirstTextValueFromNodeList(nList2);
+
+ if (StringUtils.isEmpty(base64SigString)) {
+ String msg = "DSS response not correct, Base64Signature element missing.";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.trace("Base64Signature element of DSS response: " + base64SigString);
+
+ String sigString = new String(Base64.decode(base64SigString));
+
+ try {
+ return XMLUtil.stringToDOM(sigString);
+ } catch (Exception e) {
+ String msg = "Unable to extract signature from DSS response";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+
+ }
+
+ /**
+ * Handels connection to SZR-GW and returns Identity Link on success
+ * @param citizenSignature Citizen signature
+ * @param attributeList Received attribute List in assertion
+ * @return Identity Link
+ * @throws STORKException
+ */
+ public static IdentityLink connectToSZRGateway(Element citizenSignature, List<Attribute> attributeList) throws STORKException {
+ Logger.trace("Calling SZR Gateway with the following attributes:");
+
+ String fiscalNumber = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_FISCALNUMBER);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_FISCALNUMBER + " : " + fiscalNumber);
+
+ String givenName = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_GIVENNAME);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_GIVENNAME+ " : " + givenName);
+
+ String lastName = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_SURNAME);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_SURNAME+ " : " + lastName);
+
+ String dateOfBirth = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH + " : " + dateOfBirth);
+
+ if (!StringUtils.isEmpty(dateOfBirth)) {
+ dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth);
+ }
+
+ CreateIdentityLinkResponse response;
+ IdentityLink identityLink = null;
+ try {
+ Logger.trace("Starting call...");
+ response = AuthenticationServer.getInstance().getIdentityLink(fiscalNumber, givenName, lastName, dateOfBirth, citizenSignature);
+ if (response.isError()) {
+ Logger.error("Receveid ErrorResponse from SZR Gateway.");
+ throw new SZRGWClientException(response.getError());
+ }
+ else {
+ Logger.trace("Receveid Success Response from SZR Gateway.");
+ Element samlAssertion = response.getAssertion();
+
+ IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertion);
+ 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 (SZRGWClientException e) {
+ Logger.error("Error connecting SZR-Gateway: ", e);
+ throw new STORKException("Error connecting SZR-Gateway: ", e);
+ } catch (ParseException e) {
+ Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
+ throw new STORKException("Error parsing IdentityLink received from SZR-Gateway: ", e);
+ }
+
+ return identityLink;
+
+ }
+
+
+ /**
+ * Transforms additional STORK attributes to MOA Extended attributes
+ * @param storkAttributeList STORK attribute list
+ * @return
+ */
+ public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(List<Attribute> storkAttributeList) {
+ List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>();
+
+ Logger.trace("Adding the following attributes to MOA assertion: ");
+ int count = 0;
+ //only add attributes different than eIdentifier, given name, surname, dateOfBirth, signedDoc
+ for (Attribute attribute : storkAttributeList) {
+ //attribute is not in default returned attribute set
+ if (!STORKConstants.DEFAULT_STORK_RETURNED_ATTRIBUTE_SET.contains(attribute.getName())) {
+
+ String attributeValue = null;
+ if (!attribute.getAttributeValues().isEmpty()) {
+ //we have attribute value
+ attributeValue = SAMLUtil.getStringValueFromXMLObject(attribute.getAttributeValues().get(0));
+ }
+ 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;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java new file mode 100644 index 000000000..29478718f --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java @@ -0,0 +1,88 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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 org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.RuntimeConstants; +
+/**
+ * Gets a Velocity Engine + * + * @author bzwattendorfer
+ *
+ */
+public class VelocityProvider {
+ + /** + * Gets velocityEngine from Classpath + * @return VelocityEngine + * @throws Exception + */
+ public static VelocityEngine getClassPathVelocityEngine() throws Exception {
+ VelocityEngine velocityEngine = getBaseVelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+ velocityEngine.setProperty("classpath.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+
+ velocityEngine.init();
+
+ return velocityEngine;
+ }
+ + /** + * Gets VelocityEngine from File + * @param rootPath File Path to template file + * @return VelocityEngine + * @throws Exception + */
+ public static VelocityEngine getFileVelocityEngine(String rootPath) throws Exception {
+ VelocityEngine velocityEngine = getBaseVelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
+ velocityEngine.setProperty("file.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
+ velocityEngine.setProperty("file.resource.loader.path", rootPath);
+
+ velocityEngine.init();
+
+ return velocityEngine;
+ }
+ + /** + * Gets a basic VelocityEngine + * @return VelocityEngine + */
+ private static VelocityEngine getBaseVelocityEngine() {
+ VelocityEngine velocityEngine = new VelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8");
+ velocityEngine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
+
+ return velocityEngine;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java index c719484fa..13e7cb0f1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java @@ -24,12 +24,13 @@ package at.gv.egovernment.moa.id.config; -import iaik.ixsil.util.Utils; import iaik.pki.pathvalidation.ChainingModes; import iaik.utils.RFC2253NameParser; import iaik.utils.RFC2253NameParserException; import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; import java.security.Principal; import java.util.ArrayList; import java.util.HashMap; @@ -39,20 +40,23 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.ws.message.encoder.MessageEncodingException; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.traversal.NodeIterator; -import com.sun.xml.internal.fastinfoset.stax.events.Util; - import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.data.Schema; import at.gv.egovernment.moa.id.auth.data.SchemaImpl; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameter; import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameters; +import at.gv.egovernment.moa.id.config.stork.CPEPS; +import at.gv.egovernment.moa.id.config.stork.SignatureCreationParameter; +import at.gv.egovernment.moa.id.config.stork.SignatureVerificationParameter; import at.gv.egovernment.moa.id.data.IssuerAndSerial; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; import at.gv.egovernment.moa.logging.Logger; @@ -63,6 +67,12 @@ import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.StringUtils; import at.gv.egovernment.moa.util.XPathException; import at.gv.egovernment.moa.util.XPathUtils; +import eu.stork.vidp.messages.builder.STORKMessagesBuilder; +import eu.stork.vidp.messages.common.STORKConstants; +import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel; +import eu.stork.vidp.messages.stork.RequestedAttributes; +import eu.stork.vidp.messages.util.SAMLUtil; +import eu.stork.vidp.messages.util.XMLUtil; /** * A class that builds configuration data from a DOM based representation. @@ -80,6 +90,12 @@ public class ConfigurationBuilder { protected static final String CONF = Constants.MOA_ID_CONFIG_PREFIX + ":"; /** an XPATH-Expression */ protected static final String DSIG = Constants.DSIG_PREFIX + ":"; + + /** an XPATH-Expression */ + protected static final String STORK = Constants.STORK_PREFIX + ":"; + + /** an XPATH-Expression */ + protected static final String STORKP= Constants.STORKP_PREFIX + ":"; // // chaining mode constants appearing in the configuration file @@ -220,8 +236,58 @@ public class ConfigurationBuilder { protected static final String VERIFY_INFOBOXES_INFOBOX_XPATH = CONF + "Infobox"; + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS = + ROOT + CONF + "AuthComponent/" + CONF + "ForeignIdentities/" + CONF + "STORK/" + CONF + "C-PEPS"; + + /** STORK Config AttributeName */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_COUNTRY_CODE = "countryCode"; + + /** STORK Config AttributeName */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_URL = "URL"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_CREATION_PARAMETER = + ROOT + CONF + "AuthComponent/" + CONF + "ForeignIdentities/" + CONF + "STORK/" + CONF + "SAMLSigningParameter/" + + CONF + "SignatureCreationParameter" ; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_REQUESTED_ATTRIBUTES = + STORK + "RequestedAttribute"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_VERIFICATION_PARAMETER = + ROOT + CONF + "AuthComponent/" + CONF + "ForeignIdentities/" + CONF + "STORK/" + CONF + "SAMLSigningParameter/" + + CONF + "SignatureVerificationParameter"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE = + CONF + "KeyStore"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME = + CONF + "KeyName"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE_PASSWORD = + CONF + "KeyStore/@password"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME_PASSWORD = + CONF + "KeyName/@password"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_TRUSTPROFILE_ID = + CONF + "TrustProfileID"; + /** STORK Config XPATH-Expression */ + public static final String OA_AUTH_COMPONENT_STORK_QAA = + CONF + "STORK/" + STORK + "QualityAuthenticationAssuranceLevel"; + /** STORK Config XPATH-Expression */ + public static final String OA_AUTH_COMPONENT_STORK_REQUESTED_ATTRIBUTE = + CONF + "STORK/" + STORKP + "RequestedAttributes/" + STORK + "RequestedAttribute"; + /** * main configuration file directory name used to configure MOA-ID */ @@ -615,6 +681,32 @@ public class ConfigurationBuilder { oap.setMandateProfiles(profiles); } } + + //add STORK Configuration specific to OA (RequestedAttributes, QAALevel) + QualityAuthenticationAssuranceLevel qaaLevel = buildOaSTORKQAALevel(authComponent); + if (qaaLevel != null) { + oap.setQaaLevel(qaaLevel); + Logger.debug("Using non-MOA-default STORK QAALevel for this OA " + "(" + oap.getPublicURLPrefix() + "): " + qaaLevel.getValue()); + } + + RequestedAttributes additionalRequestedAttributes = buildOaSTORKRequestedAttributes(authComponent); + + if(!additionalRequestedAttributes.getRequestedAttributes().isEmpty()) { + //we have additional STORK attributes to request for this OA + Logger.debug("Using non-MOA-default STORK RequestedAttributes for this OA " + "(" + oap.getPublicURLPrefix() + "): "); + for (RequestedAttribute addReqAttr : additionalRequestedAttributes.getRequestedAttributes()) { + if (!SAMLUtil.containsAttribute(oap.getRequestedAttributes().getRequestedAttributes(),addReqAttr.getName())) { + addReqAttr.detach(); + oap.getRequestedAttributes().getRequestedAttributes().add(addReqAttr); + Logger.debug("Requesting additional attribute: " + addReqAttr.getName() + ", isRequired: " + addReqAttr.isRequired()); + } + } + + } else { + //do nothing, only request default attributes + } + + } OA_set.add(oap); } @@ -633,7 +725,7 @@ public class ConfigurationBuilder { */ private int buildConditionLength(String length) { - if (Util.isEmptyString(length)) + if (StringUtils.isEmpty(length)) return -1; else return new Integer(length).intValue(); @@ -1035,6 +1127,228 @@ public class ConfigurationBuilder { return new VerifyInfoboxParameters(defaultIdentifiers, infoboxParameters); } } + + /** + * Creates a SignatureCreationParameter object from the MOA-ID configuration + * This configuration object contains KeyStore and Key data for signature creation (STORK SAML Signature Creation). + * + * @return KeyStore and Key data for signature creation (STORK SAML Signature Creation) + */ + public SignatureCreationParameter buildSTORKSignatureCreationParameter() { + + Logger.debug("Loading STORK signature creation parameters."); + + Element signatureCreationParameterElement = (Element)XPathUtils.selectSingleNode(configElem_, AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_CREATION_PARAMETER); + if (signatureCreationParameterElement == null) { + Logger.debug("No STORK signature parameters found, " + AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_CREATION_PARAMETER + "is missing."); + return null; + } + + SignatureCreationParameter signatureCreationParameter = new SignatureCreationParameter(); + + Element keyStoreElement = (Element)XPathUtils.selectSingleNode(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE); + if (keyStoreElement==null) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE + "is missing."); + return null; + } + + Element keyNameElement = (Element)XPathUtils.selectSingleNode(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME); + if (keyNameElement==null) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME + "is missing."); + return null; + } + + String keyStorePath = DOMUtils.getText(keyStoreElement); + if (StringUtils.isEmpty(keyStorePath)) { + Logger.error("No KeyStorePath for STORK SAML Signing Certificate provided!"); + return null; + } + signatureCreationParameter.setKeyStorePath(FileUtils.makeAbsoluteURL(keyStorePath, rootConfigFileDir_)); + Logger.trace("Found KeyStorePath for STORK SAML Signing Certificate: " + keyStorePath); + + String keyStorePassword = XPathUtils.getAttributeValue(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE_PASSWORD, ""); + signatureCreationParameter.setKeyStorePassword(keyStorePassword); + + String keyName = DOMUtils.getText(keyNameElement); + if (StringUtils.isEmpty(keyName)) { + Logger.warn(AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE_PASSWORD + "is missing."); + return null; + } + signatureCreationParameter.setKeyName(keyName); + Logger.trace("Found KeyName for STORK SAML Signing Certificate: " + keyName); + + String keyPassword = XPathUtils.getAttributeValue(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME_PASSWORD, ""); + signatureCreationParameter.setKeyPassword(keyPassword); + + Logger.info("STORK signature creation parameters loaded."); + + return signatureCreationParameter; + + } + + /** + * Creates a SignatureVerificationParameter object from the MOA-ID configuration + * This configuration object contains the TrustProfile to be used for signature verification (STORK SAML Signature Verification) + * + * @return TrustProfileID for signature verification (STORK SAML Signature Verification) + */ + public SignatureVerificationParameter buildSTORKSignatureVerificationParameter() { + + Logger.debug("Loading STORK signature verification parameters."); + + Element signatureVerificationParameterElement = (Element)XPathUtils.selectSingleNode(configElem_, AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_VERIFICATION_PARAMETER); + if (signatureVerificationParameterElement == null) { + Logger.debug("No STORK verification parameters found, " +AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_VERIFICATION_PARAMETER + "is missing."); + return null; + } + + SignatureVerificationParameter signatureVerificationParameter = new SignatureVerificationParameter(); + + String trustProfileID = XPathUtils.getElementValue(signatureVerificationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_TRUSTPROFILE_ID, null); + if (StringUtils.isEmpty(trustProfileID)) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_TRUSTPROFILE_ID + "is missing."); + return null; + } + Logger.trace("Using the following MOA-SP TrustProfile for STORK SAML signature verification: " + trustProfileID); + signatureVerificationParameter.setTrustProfileID(trustProfileID); + + Logger.info("STORK signature verification parameters loaded."); + + return signatureVerificationParameter; + } + + /** + * Builds a C-PEPS object from configuration + * @param cpepsElement DOM Element of C-PEPS from configuration + * @return C-PEPS object + */ + public CPEPS buildSTORKCpeps(Element cpepsElement) { + + String countryCode = cpepsElement.getAttribute(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_COUNTRY_CODE); + String cpepsURLString = cpepsElement.getAttribute(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_URL); + if (StringUtils.isEmpty(countryCode)) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_COUNTRY_CODE + "is missing."); + return null; + } + if (StringUtils.isEmpty(cpepsURLString)) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_URL + "is missing."); + return null; + } + + URL cpepsURL; + try { + cpepsURL = new URL(cpepsURLString); + } catch (MalformedURLException e) { + Logger.error("Provided CPEPS-URL (" + cpepsURLString + ") for country " + countryCode + " is not a URL", e); + return null; + } + CPEPS cpeps = new CPEPS(countryCode, cpepsURL); + Logger.debug("Adding C-PEPS for country: " + cpeps.getCountryCode() + ", URL: " + cpeps.getPepsURL()); + + Element reqAttributeElement; + NodeIterator reqAttributeIterator = XPathUtils.selectNodeIterator(cpepsElement, AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_REQUESTED_ATTRIBUTES); + + while ((reqAttributeElement = (Element) reqAttributeIterator.nextNode()) != null) { + RequestedAttribute requestedAttribute; + try { + requestedAttribute = (RequestedAttribute) SAMLUtil.unmarshallMessage(reqAttributeElement); + } catch (MessageEncodingException e) { + Logger.error("Provided RequestedAttributes for CPEPS from country " + countryCode + " is malformed.", e); + return null; + } + //only add if STORK attribute is correct + if (STORKConstants.FULL_STORK_ATTRIBUTE_SET.contains(requestedAttribute.getName())) { + cpeps.addCountrySpecificRequestedAttribute(requestedAttribute); + Logger.debug("Adding also country specific requested attribute for C-PEPS (" + countryCode + "): " + requestedAttribute.getName() + ", isRequired: " + requestedAttribute.isRequired()); + } else { + Logger.warn("Skipping addition of requested STORK Attribute, attribute unknown : " + requestedAttribute.getName()); + } + + } + + return cpeps; + } + + /** + * Builds the supported C-PEPS Map from configuration + * @return Map of C-PEPS + */ + public Map<String, CPEPS> buildSTORKcPEPSMap() { + + Logger.debug("Loading STORK C-PEPS information"); + + Map<String, CPEPS> cpepsMap = new HashMap<String, CPEPS>(); + + NodeIterator cpepsIterator = XPathUtils.selectNodeIterator(configElem_, AUTH_FOREIGN_IDENTITIES_STORK_CPEPS); + + Element cpepsElement; + CPEPS cpeps; + + while ((cpepsElement = (Element) cpepsIterator.nextNode()) != null) { + cpeps = buildSTORKCpeps(cpepsElement); + if (cpeps != null) { + cpepsMap.put(cpeps.getCountryCode(), cpeps); + } + } + + if(!cpepsMap.isEmpty()) { + Logger.info("STORK C-PEPS information loaded"); + } + + return cpepsMap; + + } + + /** + * Builds the required STORK QAALevel for this OA + * @param authComponentElement DOM Element of AuthComponent (from MOA configuration) + * @return STORK QAALevel for this OA + */ + public QualityAuthenticationAssuranceLevel buildOaSTORKQAALevel(Element authComponentElement) { + Element qaaLevelElement = (Element)XPathUtils.selectSingleNode(authComponentElement, OA_AUTH_COMPONENT_STORK_QAA); + + if (qaaLevelElement == null) return null; + + try { + QualityAuthenticationAssuranceLevel qaaLevel = (QualityAuthenticationAssuranceLevel) SAMLUtil.unmarshallMessage(qaaLevelElement); + return qaaLevel; + } catch (MessageEncodingException e) { + Logger.error("Could not build STORK QAALevel, using default."); + return null; + } + + } + + /** + * Builds the Requested Attributes specific for an OA + * @param authComponentElement DOM Element of AuthComponent (from MOA configuration) + * @return STORK RequestedAttributes for this OA + */ + public RequestedAttributes buildOaSTORKRequestedAttributes(Element authComponentElement) { + List<RequestedAttribute> reqAttributeList = new ArrayList<RequestedAttribute>(); + + + Element reqAttributeElement; + NodeIterator reqAttributeIterator = XPathUtils.selectNodeIterator(authComponentElement, OA_AUTH_COMPONENT_STORK_REQUESTED_ATTRIBUTE); + + while ((reqAttributeElement = (Element) reqAttributeIterator.nextNode()) != null) { + RequestedAttribute requestedAttribute; + try { + requestedAttribute = (RequestedAttribute) SAMLUtil.unmarshallMessage(reqAttributeElement); + } catch (MessageEncodingException e) { + Logger.error("Provided RequestedAttributes Online Application is malformed.", e); + return null; + } + //only add if STORK attribute is correct + if (STORKConstants.FULL_STORK_ATTRIBUTE_SET.contains(requestedAttribute.getName())) { + reqAttributeList.add(requestedAttribute); + } else { + Logger.warn("Skipping addition of requested STORK Attribute, attribute unknown : " + requestedAttribute.getName()); + } + } + + return STORKMessagesBuilder.buildRequestedAttributes(reqAttributeList); + } /** * Method warn. diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java index 04b92f209..b6ffb0c59 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java @@ -35,13 +35,17 @@ import java.util.List; import org.w3c.dom.Element; import org.w3c.dom.Node; +import eu.stork.vidp.messages.common.STORKBootstrap; + import at.gv.egovernment.moa.id.config.ConfigurationBuilder; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.ConfigurationProvider; import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.stork.STORKConfig; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.FileUtils; +import at.gv.egovernment.moa.util.StringUtils; import at.gv.egovernment.moa.util.XPathUtils; /** @@ -183,6 +187,11 @@ public class AuthConfigurationProvider extends ConfigurationProvider { */ private List trustedBKUs; + /** + * Holds general information for STORK (e.g. C-PEPS connection parameter, SAML signing parameters, etc.) + */ + private STORKConfig storkConfig; + /** * Return the single instance of configuration data. * @@ -263,7 +272,12 @@ public class AuthConfigurationProvider extends ConfigurationProvider { } catch (MalformedURLException t) { throw new ConfigurationException("config.03", null, t); } - + + //Initialize OpenSAML for STORK + Logger.trace("Starting initialization of OpenSAML..."); + STORKBootstrap.bootstrap(); + Logger.debug("OpenSAML successfully initialized"); + // build the internal datastructures builder = new ConfigurationBuilder(configElem, rootConfigFileDir); bKUConnectionParameter = builder.buildAuthBKUConnectionParameter(); @@ -293,6 +307,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider { trustedCACertificates = builder.getTrustedCACertificates(); trustedCACertificates = FileUtils.makeAbsoluteURL(trustedCACertificates, rootConfigFileDir); trustedBKUs = builder.getTrustedBKUs(); + storkConfig = new STORKConfig(builder.buildSTORKSignatureCreationParameter(),builder.buildSTORKSignatureVerificationParameter(), builder.buildSTORKcPEPSMap()); } catch (Throwable t) { throw new ConfigurationException("config.02", null, t); @@ -370,6 +385,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider { } return null; } + /** * Return a string with a url-reference to the VerifyAuthBlock trust @@ -484,4 +500,14 @@ public class AuthConfigurationProvider extends ConfigurationProvider { return defaultVerifyInfoboxParameters; } + /** + * Retruns the STORK Configuration + * @return STORK Configuration + */ + public STORKConfig getStorkConfig() { + return storkConfig; + } + + + }
\ No newline at end of file diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java index 2959d9208..091a01bf7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java @@ -24,7 +24,15 @@ package at.gv.egovernment.moa.id.config.auth; +import java.util.ArrayList; + +import org.opensaml.saml2.metadata.RequestedAttribute; + import at.gv.egovernment.moa.id.config.OAParameter; +import eu.stork.vidp.messages.builder.STORKMessagesBuilder; +import eu.stork.vidp.messages.common.STORKConstants; +import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel; +import eu.stork.vidp.messages.stork.RequestedAttributes; /** * Configuration parameters belonging to an online application, @@ -117,12 +125,28 @@ public class OAAuthParameter extends OAParameter { private String mandateProfiles; /** - * BZ + * * Type for authentication number (e.g. Firmenbuchnummer) */ private String identityLinkDomainIdentifierType; /** + * STORK QAA Level, Default = 4 + */ + private QualityAuthenticationAssuranceLevel qaaLevel = STORKMessagesBuilder.buildQualityAuthenticationAssuranceLevel(4); + + /** + * STORK RequestedAttributes for Online Application + * Default RequestedAttributes are: eIdentifier, givenName, surname, dateOfBirth + */ + private RequestedAttributes requestedAttributes = STORKMessagesBuilder.buildRequestedAttributes( + STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_EIDENTIFIER, true, null), + STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_GIVENNAME, true, null), + STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_SURNAME, true, null), + STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH, false, null)); + + +/** * Returns <code>true</code> if the Security Layer version is version 1.2, * otherwise <code>false</code>. * @return <code>true</code> if the Security Layer version is version 1.2, @@ -441,4 +465,38 @@ public class OAAuthParameter extends OAParameter { return this.mandateProfiles; } + /** + * Returns the defined STORK QAALevel + * @return STORK QAALevel + */ + public QualityAuthenticationAssuranceLevel getQaaLevel() { + return qaaLevel; + } + + /** + * Sets the STORK QAALevel + * @param qaaLevel + */ + public void setQaaLevel(QualityAuthenticationAssuranceLevel qaaLevel) { + this.qaaLevel = qaaLevel; + } + + /** + * Returns the desired STORK Requested Attributes + * @return STORK Requested Attributes + */ + public RequestedAttributes getRequestedAttributes() { + return requestedAttributes; + } + + /** + * Sets the desired STORK Requested Attributes + * @param requestedAttributes + */ + public void setRequestedAttributes(RequestedAttributes requestedAttributes) { + this.requestedAttributes = requestedAttributes; + } + + + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java new file mode 100644 index 000000000..a5b160454 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java @@ -0,0 +1,98 @@ +/**
+ *
+ */
+package at.gv.egovernment.moa.id.config.stork;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opensaml.saml2.metadata.RequestedAttribute;
+
+/**
+ * Encpasulates C-PEPS information according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class CPEPS {
+
+ /** Country Code of C-PEPS */
+ private String countryCode;
+
+ /** URL of C-PEPS */
+ private URL pepsURL;
+
+ /** Specific attributes to be requested for this C-PEPS */
+ private List<RequestedAttribute> countrySpecificRequestedAttributes = new ArrayList<RequestedAttribute>();
+
+ /**
+ * Constructs a C-PEPS
+ * @param countryCode ISO Country Code of C-PEPS
+ * @param pepsURL URL of C-PEPS
+ */
+ public CPEPS(String countryCode, URL pepsURL) {
+ super();
+ this.countryCode = countryCode;
+ this.pepsURL = pepsURL;
+ }
+
+ /**
+ * Gets the country code of this C-PEPS
+ * @return ISO country code
+ */
+ public String getCountryCode() {
+ return countryCode;
+ }
+
+ /**
+ * Sets the country code of this C-PEPS
+ * @param countryCode ISO country code
+ */
+ public void setCountryCode(String countryCode) {
+ this.countryCode = countryCode;
+ }
+
+ /**
+ * Gets the URL of this C-PEPS
+ * @return C-PEPS URL
+ */
+ public URL getPepsURL() {
+ return pepsURL;
+ }
+
+ /**
+ * Sets the C-PEPS URL
+ * @param pepsURL C-PEPS URL
+ */
+ public void setPepsURL(URL pepsURL) {
+ this.pepsURL = pepsURL;
+ }
+
+ /**
+ * Gets the country specific attributes of this C-PEPS
+ * @return List of country specific attributes
+ */
+ public List<RequestedAttribute> getCountrySpecificRequestedAttributes() {
+ return countrySpecificRequestedAttributes;
+ }
+
+ /**
+ * Sets the country specific attributes
+ * @param countrySpecificRequestedAttributes List of country specific requested attributes
+ */
+ public void setCountrySpecificRequestedAttributes(
+ List<RequestedAttribute> countrySpecificRequestedAttributes) {
+ this.countrySpecificRequestedAttributes = countrySpecificRequestedAttributes;
+ }
+
+ /**
+ * Adds a Requested attribute to the country specific attribute List
+ * @param countrySpecificRequestedAttribute Additional country specific requested attribute to add
+ */
+ public void addCountrySpecificRequestedAttribute(RequestedAttribute countrySpecificRequestedAttribute) {
+ this.countrySpecificRequestedAttributes.add(countrySpecificRequestedAttribute);
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java new file mode 100644 index 000000000..485a44421 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java @@ -0,0 +1,90 @@ +/**
+ *
+ */
+package at.gv.egovernment.moa.id.config.stork;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import at.gv.egovernment.moa.util.StringUtils;
+
+/**
+ * Encapsulates several STORK configuration parameters according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class STORKConfig {
+
+ /** STORK SAML signature creation parameters */
+ private SignatureCreationParameter signatureCreationParameter;
+
+ /** STORK SAML signature verification parameters */
+ private SignatureVerificationParameter signatureVerificationParameter;
+
+ /** Map of supported C-PEPSs */
+ private Map<String, CPEPS> cpepsMap = new HashMap<String, CPEPS>();
+
+
+ /**
+ * Constructs a STORK Config object
+ * @param signatureCreationParameter STORK SAML Signature creation parameters
+ * @param signatureVerificationParameter STORK SAML Signature verification parameters
+ * @param cpepsMap Map of supported C-PEPS
+ */
+ public STORKConfig(SignatureCreationParameter signatureCreationParameter,
+ SignatureVerificationParameter signatureVerificationParameter,
+ Map<String, CPEPS> cpepsMap) {
+ super();
+ this.signatureCreationParameter = signatureCreationParameter;
+ this.signatureVerificationParameter = signatureVerificationParameter;
+ this.cpepsMap = cpepsMap;
+ }
+
+ public SignatureCreationParameter getSignatureCreationParameter() {
+ return signatureCreationParameter;
+ }
+
+ public void setSignatureCreationParameter(
+ SignatureCreationParameter signatureCreationParameter) {
+ this.signatureCreationParameter = signatureCreationParameter;
+ }
+
+ public SignatureVerificationParameter getSignatureVerificationParameter() {
+ return signatureVerificationParameter;
+ }
+
+ public void setSignatureVerificationParameter(
+ SignatureVerificationParameter signatureVerificationParameter) {
+ this.signatureVerificationParameter = signatureVerificationParameter;
+ }
+
+ public Map<String, CPEPS> getCpepsMap() {
+ return cpepsMap;
+ }
+
+ public void setCpepsMap(Map<String, CPEPS> cpepsMap) {
+ this.cpepsMap = cpepsMap;
+ }
+
+ public boolean isSTORKAuthentication(String ccc) {
+
+ if (StringUtils.isEmpty(ccc) || this.cpepsMap.isEmpty())
+ return false;
+
+ if (this.cpepsMap.containsKey(ccc.toUpperCase()))
+ return true;
+ else
+ return false;
+
+ }
+
+ public CPEPS getCPEPS(String ccc) {
+ if (isSTORKAuthentication(ccc))
+ return this.cpepsMap.get(ccc);
+ else
+ return null;
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java new file mode 100644 index 000000000..1f66b7752 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java @@ -0,0 +1,112 @@ +/*
+ * Copyright 2003 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.config.stork;
+
+/**
+ * Encapsulates signature creation parameters according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class SignatureCreationParameter {
+
+ /** KeyStore Path */
+ private String keyStorePath;
+
+ /** KeyStore Password */
+ private String keyStorePassword;
+
+ /** Signing Key Name */
+ private String keyName;
+
+ /** Signing Key Password */
+ private String keyPassword;
+
+ /**
+ * Gets the KeyStore Path
+ * @return File Path to KeyStore
+ */
+ public String getKeyStorePath() {
+ return keyStorePath;
+ }
+
+ /**
+ * Sets the KeyStore Path
+ * @param keyStorePath Path to KeyStore
+ */
+ public void setKeyStorePath(String keyStorePath) {
+ this.keyStorePath = keyStorePath;
+ }
+
+ /**
+ * Gets the KeyStore Password
+ * @return Password to KeyStore
+ */
+ public String getKeyStorePassword() {
+ return keyStorePassword;
+ }
+
+ /**
+ * Sets the KeyStore Password
+ * @param keyStorePassword Password to KeyStore
+ */
+ public void setKeyStorePassword(String keyStorePassword) {
+ this.keyStorePassword = keyStorePassword;
+ }
+
+ /**
+ * Gets the Signing Key Name
+ * @return Siging Key Name
+ */
+ public String getKeyName() {
+ return keyName;
+ }
+
+ /**
+ * Sets the Signing Key Name
+ * @param keyName Signing Key Name
+ */
+ public void setKeyName(String keyName) {
+ this.keyName = keyName;
+ }
+
+ /**
+ * Gets the Signing Key Password
+ * @return Signing Key Password
+ */
+ public String getKeyPassword() {
+ return keyPassword;
+ }
+
+ /**
+ * Sets the Signing Key Password
+ * @param keyPassword Signing Key Password
+ */
+ public void setKeyPassword(String keyPassword) {
+ this.keyPassword = keyPassword;
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java new file mode 100644 index 000000000..2d8402e4d --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java @@ -0,0 +1,35 @@ +/**
+ *
+ */
+package at.gv.egovernment.moa.id.config.stork;
+
+/**
+ * Encapsulates Signature Verification data for STORK according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class SignatureVerificationParameter {
+
+ /** ID of the MOA-SP TrustProfile to be used for STORK SAML signature verification */
+ private String trustProfileID;
+
+ /**
+ * Gets the MOA-SP TrustProfileID
+ * @return TrustProfileID of MOA-SP for STORK signature verification
+ */
+ public String getTrustProfileID() {
+ return trustProfileID;
+ }
+
+ /**
+ * Sets the MOA-SP TrustProfileID
+ * @param trustProfileID TrustProfileID of MOA-SP for STORK signature verification
+ */
+ public void setTrustProfileID(String trustProfileID) {
+ this.trustProfileID = trustProfileID;
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java index 7b29051f3..a148aa690 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java @@ -40,9 +40,13 @@ import java.io.Reader; import java.net.HttpURLConnection; import java.net.URL; +import javax.servlet.http.HttpServletRequest; + import org.apache.regexp.RE; import org.apache.regexp.RESyntaxException; +import at.gv.egovernment.moa.util.StringUtils; + /** * * @author Rudolf Schamberger @@ -88,5 +92,47 @@ public class HTTPUtils { conn.disconnect(); return buffer.toString(); } + + /** + * Helper method to retrieve server URL including context path + * @param request HttpServletRequest + * @return Server URL including context path (e.g. http://localhost:8443/moa-id-auth + */ + public static String getBaseURL(HttpServletRequest request) { + StringBuffer buffer = new StringBuffer(getServerURL(request)); + + // add context path if available + String contextPath = request.getContextPath(); + if (!StringUtils.isEmpty(contextPath)) { + buffer.append(contextPath); + } + + return buffer.toString(); + } + + /** + * Helper method to retrieve server URL + * @param request HttpServletRequest + * @return Server URL (e.g. http://localhost:8443) + */ + public static String getServerURL(HttpServletRequest request) { + StringBuffer buffer = new StringBuffer(); + + // get protocol + String protocol = request.getScheme(); + buffer.append(protocol).append("://"); + + // server name + buffer.append(request.getServerName()); + + // add port if necessary + int port = request.getServerPort(); + if ((protocol.equals("http") && port != 80) || (protocol.equals("https") && port != 443)) { + buffer.append(':'); + buffer.append(port); + } + + return buffer.toString(); + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java index 790651adf..0862371dd 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java @@ -43,6 +43,7 @@ import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.StringUtils; public class ParamValidatorUtils {
@@ -54,10 +55,10 @@ public class ParamValidatorUtils { */
public static boolean isValidTarget(String target) {
- Logger.debug("Überprüfe Parameter Target");
+ Logger.debug("�berpr�fe Parameter Target");
// if non parameter is given return true
- if (target == null) {
+ if (StringUtils.isEmpty(target)) {
Logger.debug("Parameter Target ist null");
return true;
}
@@ -67,27 +68,57 @@ public class ParamValidatorUtils { Matcher matcher = pattern.matcher(target);
boolean b = matcher.matches();
if (b) {
- Logger.debug("Parameter Target erfolgreich überprüft");
+ Logger.debug("Parameter Target erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter Target. Target entspricht nicht den Kriterien (nur Zeichen a-z, A-Z und -, sowie 1-5 Zeichen lang)");
+ Logger.error("Fehler �berpr�fung Parameter Target. Target entspricht nicht den Kriterien (nur Zeichen a-z, A-Z und -, sowie 1-5 Zeichen lang)");
return false;
}
} /** + * Checks if the given ccc parameter is valid + * @param ccc HTTP parameter from request + * @return true if ccc is valid + */ + public static boolean isValidCCC(String ccc) { + + Logger.debug("�berpr�fe Parameter CCC"); + + // if non parameter is given return true + if (StringUtils.isEmpty(ccc)) { + Logger.debug("Parameter CCC ist null"); + return true; + } + + + Pattern pattern = Pattern.compile("[a-zA-Z]{2}"); + Matcher matcher = pattern.matcher(ccc); + boolean b = matcher.matches(); + if (b) { + Logger.debug("Parameter CCC erfolgreich �berpr�ft"); + return true; + } + else { + Logger.error("Fehler �berpr�fung Parameter CCC. CCC entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, sowie 2 Zeichen lang)"); + return false; + } + + } + + /** * Checks if the given target is valid * @param sourceID HTTP parameter from request * @return */ public static boolean isValidSourceID(String sourceID) { - Logger.debug("Überprüfe Parameter sourceID"); + Logger.debug("�berpr�fe Parameter sourceID"); // if non parameter is given return true - if (sourceID == null) { + if (StringUtils.isEmpty(sourceID)) { Logger.debug("Parameter Target ist null"); return true; } @@ -97,11 +128,11 @@ public class ParamValidatorUtils { Matcher matcher = pattern.matcher(sourceID); boolean b = matcher.matches(); if (b) { - Logger.debug("Parameter sourceID erfolgreich überprüft"); + Logger.debug("Parameter sourceID erfolgreich �berpr�ft"); return true; } else { - Logger.error("Fehler Überprüfung Parameter sourceID. SourceID entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, - und _, sowie 1-20 Zeichen lang)"); + Logger.error("Fehler �berpr�fung Parameter sourceID. SourceID entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, - und _, sowie 1-20 Zeichen lang)"); return false; } @@ -114,21 +145,21 @@ public class ParamValidatorUtils { */
public static boolean isValidUseMandate(String usemandate) {
- Logger.debug("Überprüfe Parameter useMandate");
+ Logger.debug("�berpr�fe Parameter useMandate");
// if non parameter is given return true
- if (usemandate== null) {
+ if (StringUtils.isEmpty(usemandate)) {
Logger.debug("Parameter useMandate ist null");
return true;
}
if (usemandate.compareToIgnoreCase("true") == 0 || usemandate.compareToIgnoreCase("false") == 0) {
- Logger.debug("Parameter useMandate erfolgreich überprüft");
+ Logger.debug("Parameter useMandate erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter useMandate. useMandate ist weder 'true' noch 'false')");
+ Logger.error("Fehler �berpr�fung Parameter useMandate. useMandate ist weder 'true' noch 'false')");
return false;
}
@@ -144,10 +175,10 @@ public class ParamValidatorUtils { * @return
*/
public static boolean isValidBKUURI(String bkuURI) {
- Logger.debug("Überprüfe Parameter bkuURI"); + Logger.debug("�berpr�fe Parameter bkuURI"); // if non parameter is given return true
- if (bkuURI == null) {
+ if (StringUtils.isEmpty(bkuURI)) {
Logger.debug("Parameter bkuURI ist null");
return true;
}
@@ -163,20 +194,20 @@ public class ParamValidatorUtils { bkuURI.compareToIgnoreCase("http://localhost:3495/http-security-layer-request") == 0 || bkuURI.compareToIgnoreCase("http://127.0.0.1:3495/http-security-layer-request") == 0 || bkuURI.compareToIgnoreCase("https://127.0.0.1:3496/https-security-layer-request") == 0) {
- Logger.debug("Parameter bkuURI erfolgreich überprüft");
+ Logger.debug("Parameter bkuURI erfolgreich �berpr�ft");
return true;
}
else {
- Logger.debug("Parameter bkuURI ist keine lokale BKU. Überprüfe Liste der vertrauenswürdigen BKUs.");
+ Logger.debug("Parameter bkuURI ist keine lokale BKU. �berpr�fe Liste der vertrauensw�rdigen BKUs.");
AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
List trustedBKUs = authConf.getTrustedBKUs();
boolean b = trustedBKUs.contains(bkuURI);
if (b) {
- Logger.debug("Parameter bkuURI erfolgreich überprüft");
+ Logger.debug("Parameter bkuURI erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI ist nicht auf Liste der vertrauenswürdigen BKUs (Konfigurationselement: MOA-IDConfiguration/TrustedBKUs)");
+ Logger.error("Fehler �berpr�fung Parameter bkuURI. bkuURI ist nicht auf Liste der vertrauensw�rdigen BKUs (Konfigurationselement: MOA-IDConfiguration/TrustedBKUs)");
return false;
}
}
@@ -184,16 +215,16 @@ public class ParamValidatorUtils { }
else {
- Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI beginnt nicht mit http or https");
+ Logger.error("Fehler �berpr�fung Parameter bkuURI. bkuURI beginnt nicht mit http or https");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter bkuURI", e);
+ Logger.error("Fehler �berpr�fung Parameter bkuURI", e);
return false;
} catch (ConfigurationException e) {
- Logger.error("Fehler Überprüfung Parameter bkuURI", e);
+ Logger.error("Fehler �berpr�fung Parameter bkuURI", e);
return false;
}
}
@@ -243,7 +274,7 @@ public class ParamValidatorUtils { //
// System.out.println("ret: " + ret);
//
-// Logger.error("Fehler Überprüfung Parameter bkuURI. Antwortcode von BKU ist nicht 200.");
+// Logger.error("Fehler �berpr�fung Parameter bkuURI. Antwortcode von BKU ist nicht 200.");
// return false;
// }
//
@@ -257,26 +288,26 @@ public class ParamValidatorUtils { //
//// NodeList l = doc.getElementsByTagNameNS(Constants.SL12_NS_URI, "ErrorResponse");
//// if (l.getLength() != 0) {
-//// Logger.error("Fehler Überprüfung Parameter bkuURI. ErrorResponse von BKU empfangen.");
+//// Logger.error("Fehler �berpr�fung Parameter bkuURI. ErrorResponse von BKU empfangen.");
//// return false;
//// }
//
-// Logger.debug("Parameter Template bkuURI erfolgreich überprüft");
+// Logger.debug("Parameter Template bkuURI erfolgreich �berpr�ft");
// return true;
//
//// } catch (SAXException e) {
-//// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+//// Logger.error("Fehler �berpr�fung Parameter bkuURI.", e);
//// return false;
// } catch (IOException e) {
-// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+// Logger.error("Fehler �berpr�fung Parameter bkuURI.", e);
// return false;
// } catch (ParserConfigurationException e) {
-// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+// Logger.error("Fehler �berpr�fung Parameter bkuURI.", e);
// return false;
// }
// }
// else {
-// Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI ist null.");
+// Logger.error("Fehler �berpr�fung Parameter bkuURI. bkuURI ist null.");
// return false;
// }
//
@@ -313,10 +344,10 @@ public class ParamValidatorUtils { */
public static boolean isValidTemplate(HttpServletRequest req, String template) {
- Logger.debug("Überprüfe Parameter Template bzw. bkuSelectionTemplateURL");
+ Logger.debug("�berpr�fe Parameter Template bzw. bkuSelectionTemplateURL");
// if non parameter is given return true
- if (template == null) {
+ if (StringUtils.isEmpty(template)) {
Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL ist null");
return true;
}
@@ -334,37 +365,37 @@ public class ParamValidatorUtils { if (template.startsWith(httpName) || template.startsWith(httpsName)) {
new URL(template);
- Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL erfolgreich überprüft");
+ Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL. Parameter liegt nicht am gleichen Server wie die MOA-Instanz (" + req.getServerName() + ")");
+ Logger.error("Fehler �berpr�fung Parameter Template bzw. bkuSelectionTemplateURL. Parameter liegt nicht am gleichen Server wie die MOA-Instanz (" + req.getServerName() + ")");
return false;
}
}
else {
- Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL. Paramter beginnt nicht mit http oder https.");
+ Logger.error("Fehler �berpr�fung Parameter Template bzw. bkuSelectionTemplateURL. Paramter beginnt nicht mit http oder https.");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL.", e);
+ Logger.error("Fehler �berpr�fung Parameter Template bzw. bkuSelectionTemplateURL.", e);
return false;
}
}
/**
- * Checks if the given template is valid
+ * Checks if the given sessionID is valid
* @param target HTTP parameter from request
* @return
*/
public static boolean isValidSessionID(String sessionID) {
- Logger.debug("Überprüfe Parameter MOASessionId");
+ Logger.debug("�berpr�fe Parameter MOASessionId");
// if non parameter is given return true
- if (sessionID == null) {
+ if (StringUtils.isEmpty(sessionID)) {
Logger.debug("Parameter MOASessionId ist null");
return true;
}
@@ -374,11 +405,11 @@ public class ParamValidatorUtils { Matcher matcher = pattern.matcher(sessionID);
boolean b = matcher.matches();
if (b) {
- Logger.debug("Parameter MOASessionId erfolgreich überprüft");
+ Logger.debug("Parameter MOASessionId erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter MOASessionId. MOASessionId entspricht nicht den Kriterien (nur Zeichen 0-9 und -)");
+ Logger.error("Fehler �berpr�fung Parameter MOASessionId. MOASessionId entspricht nicht den Kriterien (nur Zeichen 0-9 und -)");
return false;
}
@@ -394,9 +425,9 @@ public class ParamValidatorUtils { * @return
*/
public static boolean isValidOA(String oa) {
- Logger.debug("Überprüfe Parameter oa");
+ Logger.debug("�berpr�fe Parameter oa");
// if non parameter is given return true
- if (oa == null) {
+ if (StringUtils.isEmpty(oa)) {
Logger.debug("Parameter oa ist null");
return true;
}
@@ -407,16 +438,16 @@ public class ParamValidatorUtils { // check if template url starts with http or https
if (oa.startsWith("http") || oa.startsWith("https")) {
new URL(oa);
- Logger.debug("Parameter oa erfolgreich überprüft");
+ Logger.debug("Parameter oa erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter oa. oa beginnt nicht mit http or https");
+ Logger.error("Fehler �berpr�fung Parameter oa. oa beginnt nicht mit http or https");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter oa", e);
+ Logger.error("Fehler �berpr�fung Parameter oa", e);
return false;
}
@@ -429,10 +460,10 @@ public class ParamValidatorUtils { */
public static boolean isValidSignUrl(String signurl) {
- Logger.debug("Überprüfe Parameter signurl");
+ Logger.debug("�berpr�fe Parameter signurl");
// if non parameter is given return true
- if (signurl == null) {
+ if (StringUtils.isEmpty(signurl)) {
Logger.debug("Parameter signurl ist null");
return true;
}
@@ -443,16 +474,16 @@ public class ParamValidatorUtils { // check if signurl starts with http or https
if (signurl.startsWith("http") || signurl.startsWith("https")) {
new URL(signurl);
- Logger.debug("Parameter signurl erfolgreich überprüft");
+ Logger.debug("Parameter signurl erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter signurl. signurl beginnt nicht mit http or https");
+ Logger.error("Fehler �berpr�fung Parameter signurl. signurl beginnt nicht mit http or https");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter signurl", e);
+ Logger.error("Fehler �berpr�fung Parameter signurl", e);
return false;
}
@@ -508,27 +539,27 @@ public class ParamValidatorUtils { public static boolean isValidXMLDocument(String document) {
- if (document == null)
+ if (StringUtils.isEmpty(document))
return false;
- Logger.debug("Überprüfe Parameter XMLDocument");
+ Logger.debug("Überprüfe Parameter XMLDocument");
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(document));
builder.parse(is);
- Logger.debug("Parameter XMLDocument erfolgreich überprüft");
+ Logger.debug("Parameter XMLDocument erfolgreich überprüft");
return true;
} catch (ParserConfigurationException e) {
- Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
return false;
} catch (SAXException e) {
- Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
return false;
} catch (IOException e) {
- Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
return false;
}
|