From 9acf3c2e8aca9016daf76785747d838cdc5b0330 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 9 Jul 2018 10:11:25 +0200 Subject: add SL20 connecter-backend in a first beta version (getCertificate looks good, create signature is untested) --- .../gv/egiz/pdfas/web/sl20/JsonSecurityUtils.java | 381 +++++++++++++++++++++ .../at/gv/egiz/pdfas/web/sl20/KeyStoreUtils.java | 222 ++++++++++++ .../egiz/pdfas/web/sl20/SL20HttpBindingUtils.java | 47 +++ .../java/at/gv/egiz/pdfas/web/sl20/X509Utils.java | 62 ++++ 4 files changed, 712 insertions(+) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/JsonSecurityUtils.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/KeyStoreUtils.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/X509Utils.java (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20') diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/JsonSecurityUtils.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/JsonSecurityUtils.java new file mode 100644 index 00000000..141808de --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/JsonSecurityUtils.java @@ -0,0 +1,381 @@ +package at.gv.egiz.pdfas.web.sl20; + +import java.io.IOException; +import java.security.Key; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.bouncycastle.util.encoders.Base64Encoder; +import org.jose4j.jwa.AlgorithmConstraints; +import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; +import org.jose4j.jwe.JsonWebEncryption; +import org.jose4j.jws.AlgorithmIdentifiers; +import org.jose4j.jws.JsonWebSignature; +import org.jose4j.jwx.JsonWebStructure; +import org.jose4j.keys.X509Util; +import org.jose4j.keys.resolvers.X509VerificationKeyResolver; +import org.jose4j.lang.JoseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; + +import at.gv.egiz.pdfas.web.config.WebConfiguration; +import at.gv.egiz.sl20.data.VerificationResult; +import at.gv.egiz.sl20.exceptions.SL20Exception; +import at.gv.egiz.sl20.exceptions.SL20SecurityException; +import at.gv.egiz.sl20.exceptions.SLCommandoBuildException; +import at.gv.egiz.sl20.exceptions.SLCommandoParserException; +import at.gv.egiz.sl20.utils.IJOSETools; +import at.gv.egiz.sl20.utils.SL20Constants; + +public class JsonSecurityUtils implements IJOSETools{ + + private static final Logger logger = LoggerFactory.getLogger(JsonSecurityUtils.class); + + private Key signPrivKey = null; + private X509Certificate[] signCertChain = null; + private Key encPrivKey = null; + private X509Certificate[] encCertChain = null; + private List trustedCerts = new ArrayList(); + + private boolean isInitialized = false; + + private static JsonSecurityUtils instance = null; + + public static JsonSecurityUtils getInstance() { + if (instance == null) { + instance = new JsonSecurityUtils(); + instance.initalize(); + } + + return instance; + } + + private JsonSecurityUtils() { + + + } + + protected synchronized void initalize() { + logger.info("Initialize SL2.0 authentication security constrains ... "); + try { + String keyStorePath = getKeyStoreFilePath(); + + if (StringUtils.isNotEmpty(keyStorePath)) { + KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), + getKeyStorePassword()); + + //load signing key + signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray()); + Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias()); + signCertChain = new X509Certificate[certChainSigning.length]; + for (int i=0; i aliases = keyStore.aliases(); + while(aliases.hasMoreElements()) { + String el = aliases.nextElement(); + logger.trace("Process TrustStoreEntry: " + el); + if (keyStore.isCertificateEntry(el)) { + Certificate cert = keyStore.getCertificate(el); + if (cert != null && cert instanceof X509Certificate) + trustedCerts.add((X509Certificate) cert); + else + logger.info("Can not process entry: " + el + ". Reason: " + cert.toString()); + + } + } + + //some short validation + if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) { + logger.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); + throw new SL20Exception("sl20.03"); + + } + + if (signCertChain == null || signCertChain.length == 0) { + logger.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); + throw new SL20Exception("sl20.03"); + + } + + isInitialized = true; + logger.info("SL2.0 authentication security constrains initialized."); + + } else + logger.info("SL2.0 security constrains not configurated!"); + + } catch ( Exception e) { + logger.error("SL2.0 security constrains initialization FAILED.", e); + + } + + } + + + @Override + public String createSignature(String payLoad) throws SLCommandoBuildException { + try { + JsonWebSignature jws = new JsonWebSignature(); + + //set payload + jws.setPayload(payLoad); + + //set basic header + jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND); + + //set signing information + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); + jws.setKey(signPrivKey); + + //TODO: + jws.setCertificateChainHeaderValue(signCertChain); + jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]); + + return jws.getCompactSerialization(); + + } catch (JoseException e) { + logger.warn("Can NOT sign SL2.0 command.", e); + throw new SLCommandoBuildException(e); + + } + + } + + @Override + public VerificationResult validateSignature(String serializedContent) throws SL20Exception { + try { + JsonWebSignature jws = new JsonWebSignature(); + //set payload + jws.setCompactSerialization(serializedContent); + + //set security constrains + jws.setAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()]))); + + //load signinc certs + Key selectedKey = null; + List x5cCerts = jws.getCertificateChainHeaderValue(); + String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue(); + if (x5cCerts != null) { + logger.debug("Found x509 certificate in JOSE header ... "); + logger.trace("Sorting received X509 certificates ... "); + List sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + + if (trustedCerts.contains(sortedX5cCerts.get(0))) { + selectedKey = sortedX5cCerts.get(0).getPublicKey(); + + } else { + logger.info("Can NOT find JOSE certificate in truststore."); + logger.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString()); + try { + logger.debug("Cert: " + Base64.getEncoder().encodeToString(sortedX5cCerts.get(0).getEncoded())); + + } catch (CertificateEncodingException e) { + e.printStackTrace(); + + } + + } + + } else if (StringUtils.isNotEmpty(x5t256)) { + logger.debug("Found x5t256 fingerprint in JOSE header .... "); + X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts); + selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.emptyList()); + + } else { + logger.info("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint"); + throw new SLCommandoParserException(); + + } + + if (selectedKey == null) { + logger.info("Can NOT select verification key for JWS. Signature verification FAILED."); + throw new SLCommandoParserException(); + + } + + //set verification key + jws.setKey(selectedKey); + + //validate signature + boolean valid = jws.verifySignature(); + if (!valid) { + logger.info("JWS signature invalide. Stopping authentication process ..."); + logger.debug("Received JWS msg: " + serializedContent); + throw new SL20SecurityException(); + + } + + + //load payLoad + logger.debug("SL2.0 commando signature validation sucessfull"); + JsonElement sl20Req = new JsonParser().parse(jws.getPayload()); + + return new VerificationResult(sl20Req.getAsJsonObject(), null, valid) ; + + } catch (JoseException e) { + logger.warn("SL2.0 commando signature validation FAILED", e); + throw new SL20SecurityException(e); + + } + + } + + + @Override + public JsonElement decryptPayload(String compactSerialization) throws SL20Exception { + try { + JsonWebEncryption receiverJwe = new JsonWebEncryption(); + + //set security constrains + receiverJwe.setAlgorithmConstraints( + new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()]))); + receiverJwe.setContentEncryptionAlgorithmConstraints( + new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()]))); + + //set payload + receiverJwe.setCompactSerialization(compactSerialization); + + + //validate key from header against key from config + List x5cCerts = receiverJwe.getCertificateChainHeaderValue(); + String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue(); + if (x5cCerts != null) { + logger.debug("Found x509 certificate in JOSE header ... "); + logger.trace("Sorting received X509 certificates ... "); + List sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + + if (!sortedX5cCerts.get(0).equals(encCertChain[0])) { + logger.info("Certificate from JOSE header does NOT match encryption certificate"); + logger.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString()); + + try { + logger.debug("Cert: " + Base64.getEncoder().encodeToString(sortedX5cCerts.get(0).getEncoded())); + } catch (CertificateEncodingException e) { + e.printStackTrace(); + } + throw new SL20Exception("sl20.05"); + } + + } else if (StringUtils.isNotEmpty(x5t256)) { + logger.debug("Found x5t256 fingerprint in JOSE header .... "); + String certFingerPrint = X509Util.x5tS256(encCertChain[0]); + if (!certFingerPrint.equals(x5t256)) { + logger.info("X5t256 from JOSE header does NOT match encryption certificate"); + logger.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint); + throw new SL20Exception("sl20.05"); + + } + + } else { + logger.info("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint"); + throw new SLCommandoParserException(); + + } + + //set key + receiverJwe.setKey(encPrivKey); + + + //decrypt payload + return new JsonParser().parse(receiverJwe.getPlaintextString()); + + } catch (JoseException e) { + logger.warn("SL2.0 result decryption FAILED", e); + throw new SL20SecurityException(e); + + } catch ( JsonSyntaxException e) { + logger.warn("Decrypted SL2.0 result is NOT a valid JSON.", e); + throw new SLCommandoParserException(e); + + } + + } + + + + @Override + public X509Certificate getEncryptionCertificate() { + //TODO: maybe update after SL2.0 update on encryption certificate parts + if (encCertChain !=null && encCertChain.length > 0) + return encCertChain[0]; + else + return null; + } + + @Override + public boolean isInitialized() { + return isInitialized; + + } + + private String getKeyStoreFilePath() { + return WebConfiguration.getSL20KeyStorePath(); + } + + private String getKeyStorePassword() { + return WebConfiguration.getSL20KeyStorePassword(); + + } + + private String getSigningKeyAlias() { + return WebConfiguration.getSL20KeySigningAlias(); + } + + private String getSigningKeyPassword() { + return WebConfiguration.getSL20KeySigningPassword(); + + } + + private String getEncryptionKeyAlias() { + return WebConfiguration.getSL20KeyEncryptionAlias(); + } + + private String getEncryptionKeyPassword() { + return WebConfiguration.getSL20KeyEncryptionPassword(); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/KeyStoreUtils.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/KeyStoreUtils.java new file mode 100644 index 00000000..c7472a22 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/KeyStoreUtils.java @@ -0,0 +1,222 @@ +/* + * 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.egiz.pdfas.web.sl20; + +import iaik.x509.X509Certificate; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.Certificate; + +/** + * Utility for creating and loading key stores. + * + * @author Paul Ivancsics + * @version $Id$ + */ +public class KeyStoreUtils { + + /** + * JAVA KeyStore + */ + private static final String KEYSTORE_TYPE_JKS = "JKS"; + + /** + * PKCS12 KeyStore + */ + private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12"; + + + + /** + * Loads a key store from file. + * + * @param keystoreType key store type + * @param urlString URL of key store + * @param password password protecting the key store + * @return key store loaded + * @throws IOException thrown while reading the key store from file + * @throws GeneralSecurityException thrown while creating the key store + */ + public static KeyStore loadKeyStore( + String keystoreType, + String urlString, + String password) + throws IOException, GeneralSecurityException { + + URL keystoreURL = new URL(urlString); + InputStream in = keystoreURL.openStream(); + return loadKeyStore(keystoreType, in, password); + } + /** + * Loads a key store from an InputStream, and + * closes the InputStream. + * + * @param keystoreType key store type + * @param in input stream + * @param password password protecting the key store + * @return key store loaded + * @throws IOException thrown while reading the key store from the stream + * @throws GeneralSecurityException thrown while creating the key store + */ + public static KeyStore loadKeyStore( + String keystoreType, + InputStream in, + String password) + throws IOException, GeneralSecurityException { + + char[] chPassword = null; + if (password != null) + chPassword = password.toCharArray(); + KeyStore ks = KeyStore.getInstance(keystoreType); + ks.load(in, chPassword); + in.close(); + return ks; + } + /** + * Creates a key store from X509 certificate files, aliasing them with + * the index in the String[], starting with "0". + * + * @param keyStoreType key store type + * @param certFilenames certificate filenames + * @return key store created + * @throws IOException thrown while reading the certificates from file + * @throws GeneralSecurityException thrown while creating the key store + */ + public static KeyStore createKeyStore( + String keyStoreType, + String[] certFilenames) + throws IOException, GeneralSecurityException { + + KeyStore ks = KeyStore.getInstance(keyStoreType); + ks.load(null, null); + for (int i = 0; i < certFilenames.length; i++) { + Certificate cert = loadCertificate(certFilenames[i]); + ks.setCertificateEntry("" + i, cert); + } + return ks; + } +// /** +// * Creates a key store from a directory containg X509 certificate files, +// * aliasing them with the index in the String[], starting with "0". +// * All the files in the directory are considered to be certificates. +// * +// * @param keyStoreType key store type +// * @param certDirURLString file URL of directory containing certificate filenames +// * @return key store created +// * @throws IOException thrown while reading the certificates from file +// * @throws GeneralSecurityException thrown while creating the key store +// */ +// public static KeyStore createKeyStoreFromCertificateDirectory( +// String keyStoreType, +// String certDirURLString) +// throws IOException, GeneralSecurityException { +// +// URL certDirURL = new URL(certDirURLString); +// String certDirname = certDirURL.getFile(); +// File certDir = new File(certDirname); +// String[] certFilenames = certDir.list(); +// String separator = +// (certDirname.endsWith(File.separator) ? "" : File.separator); +// for (int i = 0; i < certFilenames.length; i++) { +// certFilenames[i] = certDirname + separator + certFilenames[i]; +// } +// return createKeyStore(keyStoreType, certFilenames); +// } + + /** + * Loads an X509 certificate from file. + * @param certFilename filename + * @return the certificate loaded + * @throws IOException thrown while reading the certificate from file + * @throws GeneralSecurityException thrown while creating the certificate + */ + private static Certificate loadCertificate(String certFilename) + throws IOException, GeneralSecurityException { + + FileInputStream in = new FileInputStream(certFilename); + Certificate cert = new X509Certificate(in); + in.close(); + return cert; + } + + + /** + * Loads a keyStore without knowing the keyStore type + * @param keyStorePath URL to the keyStore + * @param password Password protecting the keyStore + * @return keyStore loaded + * @throws KeyStoreException thrown if keyStore cannot be loaded + * @throws FileNotFoundException + * @throws IOException + */ + public static KeyStore loadKeyStore(String keyStorePath, String password) throws KeyStoreException, IOException{ + + //InputStream is = new FileInputStream(keyStorePath); + URL keystoreURL = new URL(keyStorePath); + InputStream in = keystoreURL.openStream(); + InputStream isBuffered = new BufferedInputStream(in); + return loadKeyStore(isBuffered, password); + + } + + /** + * Loads a keyStore without knowing the keyStore type + * @param in input stream + * @param password Password protecting the keyStore + * @return keyStore loaded + * @throws KeyStoreException thrown if keyStore cannot be loaded + * @throws FileNotFoundException + * @throws IOException + */ +public static KeyStore loadKeyStore(InputStream is, String password) throws KeyStoreException, IOException{ + is.mark(1024*1024); + KeyStore ks = null; + try { + try { + ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password); + } catch (IOException e2) { + is.reset(); + ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password); + } + } catch(Exception e) { + e.printStackTrace(); + //throw new KeyStoreException(e); + } + return ks; + + } + + + + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java new file mode 100644 index 00000000..f5d6ff55 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java @@ -0,0 +1,47 @@ +package at.gv.egiz.pdfas.web.sl20; + +import java.io.IOException; +import java.io.StringWriter; +import java.net.URISyntaxException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ContentType; +import org.jose4j.base64url.Base64Url; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonObject; + +import at.gv.egiz.sl20.utils.SL20Constants; + +public class SL20HttpBindingUtils { + private static final org.slf4j.Logger log = LoggerFactory.getLogger(SL20HttpBindingUtils.class); + + public static void writeIntoResponse(HttpServletRequest request, HttpServletResponse response, JsonObject sl20Forward, String redirectURL) throws IOException, URISyntaxException { + //forward SL2.0 command + if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && + request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { + log.debug("Client request containts 'native client' header ... "); + StringWriter writer = new StringWriter(); + writer.write(sl20Forward.toString()); + final byte[] content = writer.toString().getBytes("UTF-8"); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentLength(content.length); + response.setContentType(ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(content); + + } else { + log.debug("Client request containts is no native client ... "); + URIBuilder clientRedirectURI = new URIBuilder(redirectURL); + clientRedirectURI.addParameter( + SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, + Base64Url.encode(sl20Forward.toString().getBytes())); + response.setStatus(307); + response.setHeader("Location", clientRedirectURI.build().toString()); + + } + + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/X509Utils.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/X509Utils.java new file mode 100644 index 00000000..391b8271 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/X509Utils.java @@ -0,0 +1,62 @@ +package at.gv.egiz.pdfas.web.sl20; + +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +public class X509Utils { + + /** + * Sorts the Certificate Chain by IssuerDN and SubjectDN. The [0]-Element should be the Hostname, + * the last Element should be the Root Certificate. + * + * @param certs + * The first element must be the correct one. + * @return sorted Certificate Chain + */ + public static List sortCertificates( + List certs) + { + int length = certs.size(); + if (certs.size() <= 1) + { + return certs; + } + + for (X509Certificate cert : certs) + { + if (cert == null) + { + throw new NullPointerException(); + } + } + + for (int i = 0; i < length; i++) + { + boolean found = false; + X500Principal issuer = certs.get(i).getIssuerX500Principal(); + for (int j = i + 1; j < length; j++) + { + X500Principal subject = certs.get(j).getSubjectX500Principal(); + if (issuer.equals(subject)) + { + // sorting necessary? + if (i + 1 != j) + { + X509Certificate tmp = certs.get(i + 1); + certs.set(i + 1, certs.get(j)); + certs.set(j, tmp); + } + found = true; + } + } + if (!found) + { + break; + } + } + + return certs; + } +} -- cgit v1.2.3 From a5541ab96512cb78d493516ecf0dfb94a6544f52 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 26 Jul 2018 11:23:47 +0200 Subject: add logger on trace level for request/response debugging --- .../src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java | 1 + 1 file changed, 1 insertion(+) (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20') diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java index f5d6ff55..e43ebfcf 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/sl20/SL20HttpBindingUtils.java @@ -21,6 +21,7 @@ public class SL20HttpBindingUtils { public static void writeIntoResponse(HttpServletRequest request, HttpServletResponse response, JsonObject sl20Forward, String redirectURL) throws IOException, URISyntaxException { //forward SL2.0 command + log.trace("SL20 command: " + sl20Forward.toString()); if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { log.debug("Client request containts 'native client' header ... "); -- cgit v1.2.3