diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-11-04 09:50:25 +0100 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-11-04 09:50:25 +0100 |
commit | 518839d9ade1e97d878e494903e088a5b0cf0359 (patch) | |
tree | 954b008011b4689e19710da6e3797079e68bc315 /id/server | |
parent | 7ed5f3385e7f8f9a455556404ded37e789a6e8e7 (diff) | |
download | moa-id-spss-518839d9ade1e97d878e494903e088a5b0cf0359.tar.gz moa-id-spss-518839d9ade1e97d878e494903e088a5b0cf0359.tar.bz2 moa-id-spss-518839d9ade1e97d878e494903e088a5b0cf0359.zip |
update Http client for MIS communication
Diffstat (limited to 'id/server')
9 files changed, 163 insertions, 220 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java index 8e98c5129..7e0f48744 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java @@ -1297,4 +1297,18 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide return false; } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.commons.api.AuthConfiguration#getBasicMOAIDConfigurationBoolean(java.lang.String, boolean) + */ + @Override + public boolean getBasicMOAIDConfigurationBoolean(String key, boolean defaultValue) { + String value = properties.getProperty(key); + + if (MiscUtil.isNotEmpty(value)) + return Boolean.valueOf(value); + + return defaultValue; + } + } diff --git a/id/server/moa-id-commons/pom.xml b/id/server/moa-id-commons/pom.xml index a3d902262..d8d2e0d3d 100644 --- a/id/server/moa-id-commons/pom.xml +++ b/id/server/moa-id-commons/pom.xml @@ -81,6 +81,17 @@ </exclusions> </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + </dependency> + + <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java index 2a8f8727a..d2c827d55 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java @@ -11,7 +11,12 @@ import iaik.pki.revocation.RevocationSourceTypes; public interface AuthConfiguration extends ConfigurationProvider{ + public static final String PROP_KEY_SSL_HOSTNAME_VALIDATION = "configuration.ssl.validation.hostname"; + public static final String PROP_KEY_OVS_SSL_HOSTNAME_VALIDATION = "service.onlinemandates.ssl.validation.hostname"; + public static final String DEFAULT_X509_CHAININGMODE = "pkix"; + + public Properties getGeneralPVP2ProperiesConfig(); @@ -187,4 +192,13 @@ public interface AuthConfiguration extends ConfigurationProvider{ * @return Array of {@link RevocationSourceTypes} values */ public String[] getRevocationMethodOrder(); + + /** + * Get a boolean value from basic MOA-ID configuration file + * + * @param key Configuration key + * @param defaultValue Default result + * @return returns the value of the configuration key, or the default value if the key is not set + */ + public boolean getBasicMOAIDConfigurationBoolean(String key, boolean defaultValue); } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/HttpClientWithProxySupport.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/HttpClientWithProxySupport.java index 733c03bf0..7121c4a2a 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/HttpClientWithProxySupport.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/HttpClientWithProxySupport.java @@ -22,9 +22,20 @@ */ package at.gv.egovernment.moa.id.commons.utils; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -35,27 +46,55 @@ import at.gv.egovernment.moa.util.MiscUtil; */ public class HttpClientWithProxySupport { - public static HttpClient getHttpClient() { - HttpClient client = new HttpClient(); - + public static CloseableHttpClient getHttpClient(SSLSocketFactory sSLSocketFactory, boolean validateHostname) { + + HttpClientBuilder clientBuilder = HttpClients.custom(); + + //set proxy functionality String host = System.getProperty("http.proxyHost"); //$NON-NLS-1$ - String port = System.getProperty("http.proxyPort"); //$NON-NLS-1$ - if (MiscUtil.isNotEmpty(host) && - MiscUtil.isNotEmpty(port)) { - int p = Integer.parseInt(port); - client.getHostConfiguration().setProxy(host, p); + String port = System.getProperty("http.proxyPort"); //$NON-NLS-1$ + int p = -1; + + if (MiscUtil.isNotEmpty(host) && MiscUtil.isNotEmpty(port)) { + p = Integer.parseInt(port); + HttpHost proxy = null; + if (host.startsWith("https")) + proxy = new HttpHost(host, p, "https"); + else + proxy = new HttpHost(host, p, "http"); + + clientBuilder.setProxy(proxy); + Logger.info("Initial HTTPClient with proxy usage. " + "ProxyHost=" + host + " ProxyPort=" + port); - + String user = System.getProperty("http.proxyUser"); //$NON-NLS-1$ String pass = System.getProperty("http.proxyPassword"); //$NON-NLS-1$ - if (MiscUtil.isNotEmpty(user) && pass != null) { - client.getState().setProxyCredentials(new AuthScope(host, p), - new UsernamePasswordCredentials(user, pass)); + if (MiscUtil.isNotEmpty(user) && pass != null) { + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(new AuthScope(host, p), new UsernamePasswordCredentials(user, pass)); } - } - return client; + } + + //set SSL context + if (sSLSocketFactory != null) { + HostnameVerifier hostnameVerifier = null; + + //set hostName validation filter + if (validateHostname) + hostnameVerifier = new DefaultHostnameVerifier(); + else + hostnameVerifier = new NoopHostnameVerifier(); + + clientBuilder.setSSLSocketFactory( + new SSLConnectionSocketFactory(sSLSocketFactory, hostnameVerifier)); + + } + + + + return clientBuilder.build(); } } diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java index a24cc9a43..3383cf201 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java @@ -79,7 +79,7 @@ public class GetMISSessionIDTask extends AbstractAuthServletTask { authConfig, connectionParameters); List<MISMandate> list = MISSimpleClient.sendGetMandatesRequest( - connectionParameters.getUrl(), misSessionID, sslFactory); + connectionParameters.getUrl(), misSessionID, sslFactory, authConfig); //check if mandates received if (list == null || list.size() == 0) { diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java index 8acfd255b..975dec429 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java @@ -122,7 +122,8 @@ public class PrepareGetMISMandateTask extends AbstractAuthServletTask { profiles, targetType, authBlock, - sslFactory); + sslFactory, + authConfig); if (misSessionID == null) { Logger.error("Fehler bei Anfrage an Vollmachten Service. MIS Session ID ist null."); diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWSecureSocketFactory.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWSecureSocketFactory.java deleted file mode 100644 index 22b575489..000000000 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWSecureSocketFactory.java +++ /dev/null @@ -1,170 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - ******************************************************************************/ -/* - * 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.auth.validator.parep.client.szrgw; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import javax.net.ssl.SSLSocketFactory; - -import org.apache.commons.httpclient.params.HttpConnectionParams; -import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; - -/** - * This class implements a secure protocol socket factory - * for the Apache HTTP client. - * - * @author <a href="mailto:peter.danner@egiz.gv.at">Peter Danner</a> - */ -public class SZRGWSecureSocketFactory implements SecureProtocolSocketFactory { - - /** - * The SSL socket factory. - */ - private SSLSocketFactory factory; - - /** - * Creates a new Secure socket factory for the - * Apache HTTP client. - * - * @param factory the SSL socket factory to use. - */ - public SZRGWSecureSocketFactory(SSLSocketFactory factory) { - this.factory = factory; - } - - - /** - * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int) - */ - public Socket createSocket( - String host, - int port, - InetAddress clientHost, - int clientPort) - throws IOException, UnknownHostException { - - return this.factory.createSocket( - host, - port, - clientHost, - clientPort - ); - } - - /** - * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) - */ - public Socket createSocket(String host, int port) - throws IOException, UnknownHostException { - return this.factory.createSocket( - host, - port - ); - } - - /** - * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) - */ - public Socket createSocket( - Socket socket, - String host, - int port, - boolean autoClose) - throws IOException, UnknownHostException { - return this.factory.createSocket( - socket, - host, - port, - autoClose - ); - } - - /** - * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int,org.apache.commons.httpclient.params.HttpConnectionParams) - */ - public Socket createSocket( - String host, - int port, - InetAddress clientHost, - int clientPort, - HttpConnectionParams params) - throws IOException, UnknownHostException, org.apache.commons.httpclient.ConnectTimeoutException { - - Socket socket = createSocket(host, port, clientHost, clientPort); - if (socket != null) { - // socket.setKeepAlive(false); - if (params.getReceiveBufferSize() >= 0) - socket.setReceiveBufferSize(params.getReceiveBufferSize()); - if (params.getSendBufferSize() >= 0) - socket.setSendBufferSize(params.getSendBufferSize()); - socket.setReuseAddress(true); - if (params.getSoTimeout() >= 0) - socket.setSoTimeout(params.getSoTimeout()); - } - return socket; - - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object obj) { - return ((obj != null) && obj.getClass().equals(SZRGWSecureSocketFactory.class)); - } - - /** - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return SZRGWSecureSocketFactory.class.hashCode(); - } - -} - diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java index 12e58342a..26d50905e 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java @@ -56,10 +56,12 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; import org.apache.xpath.XPathAPI; import org.w3c.dom.DOMException; import org.w3c.dom.Document; @@ -69,7 +71,7 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.auth.exception.MISSimpleClientException; -import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWSecureSocketFactory; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.utils.HttpClientWithProxySupport; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.logging.Logger; @@ -96,21 +98,14 @@ public class MISSimpleClient { } } - public static List<MISMandate> sendGetMandatesRequest(String webServiceURL, String sessionId, SSLSocketFactory sSLSocketFactory) throws MISSimpleClientException { + public static List<MISMandate> sendGetMandatesRequest(String webServiceURL, String sessionId, SSLSocketFactory sSLSocketFactory, AuthConfiguration authConfig) throws MISSimpleClientException { if (webServiceURL == null) { throw new NullPointerException("Argument webServiceURL must not be null."); } if (sessionId == null) { throw new NullPointerException("Argument sessionId must not be null."); } - - // ssl settings - if (sSLSocketFactory != null) { - SZRGWSecureSocketFactory fac = new SZRGWSecureSocketFactory(sSLSocketFactory); - Protocol.registerProtocol("https", new Protocol("https", fac, 443)); - } - - + try { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest"); @@ -119,7 +114,11 @@ public class MISSimpleClient { mirElement.appendChild(sessionIdElement); // send soap request - Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement); + Element mandateIssueResponseElement = sendSOAPRequest( + webServiceURL, + mirElement, + sSLSocketFactory, + authConfig); // check for error checkForError(mandateIssueResponseElement); @@ -160,7 +159,7 @@ public class MISSimpleClient { } } - public static MISSessionId sendSessionIdRequest(String webServiceURL, byte[] idl, byte[] cert, String oaFriendlyName, String redirectURL, String referenceValue, List<String> mandateIdentifier, String targetType, byte[] authBlock, SSLSocketFactory sSLSocketFactory) throws MISSimpleClientException { + public static MISSessionId sendSessionIdRequest(String webServiceURL, byte[] idl, byte[] cert, String oaFriendlyName, String redirectURL, String referenceValue, List<String> mandateIdentifier, String targetType, byte[] authBlock, SSLSocketFactory sSLSocketFactory, AuthConfiguration authConfig) throws MISSimpleClientException { if (webServiceURL == null) { throw new MISSimpleClientException("service.04"); } @@ -170,13 +169,7 @@ public class MISSimpleClient { if (redirectURL == null) { throw new NullPointerException("Argument redirectURL must not be null."); } - - // ssl settings - if (sSLSocketFactory != null) { - SZRGWSecureSocketFactory fac = new SZRGWSecureSocketFactory(sSLSocketFactory); - Protocol.registerProtocol("https", new Protocol("https", fac, 443)); - } - + try { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest"); @@ -233,7 +226,11 @@ public class MISSimpleClient { mirElement.appendChild(authBlockElement); // send soap request - Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement); + Element mandateIssueResponseElement = sendSOAPRequest( + webServiceURL, + mirElement, + sSLSocketFactory, + authConfig); // check for error checkForError(mandateIssueResponseElement); @@ -284,7 +281,9 @@ public class MISSimpleClient { } } - private static Element sendSOAPRequest(String webServiceURL, Element request) throws MISSimpleClientException { + private static Element sendSOAPRequest(String webServiceURL, Element request, + SSLSocketFactory sSLSocketFactory, + AuthConfiguration authConfig) throws MISSimpleClientException { // try { // System.out.println("REQUEST-MIS: \n" + DOMUtils.serializeNode(request)); @@ -300,18 +299,32 @@ public class MISSimpleClient { if (request == null) { throw new NullPointerException("Argument request must not be null."); } + + CloseableHttpClient httpclient = null; + CloseableHttpResponse httpResp = null; try { - HttpClient httpclient = HttpClientWithProxySupport.getHttpClient(); - PostMethod post = new PostMethod(webServiceURL); - StringRequestEntity re = new StringRequestEntity(DOMUtils.serializeNode(packIntoSOAP(request)),"text/xml", "UTF-8"); - post.setRequestEntity(re); - int responseCode = httpclient.executeMethod(post); + httpclient = HttpClientWithProxySupport.getHttpClient( + sSLSocketFactory, + authConfig.getBasicMOAIDConfigurationBoolean(AuthConfiguration.PROP_KEY_OVS_SSL_HOSTNAME_VALIDATION, true)); + // set http POST Request + HttpPost post = new HttpPost(webServiceURL); + HttpEntity postReq = new StringEntity( + DOMUtils.serializeNode(packIntoSOAP(request)), + ContentType.create("text/xml", "UTF-8") ); + post.setEntity(postReq); + + //request webService + httpResp = httpclient.execute(post); + + //parse response + int responseCode = httpResp.getStatusLine().getStatusCode(); if (responseCode != 200) { throw new MISSimpleClientException("Invalid HTTP response code " + responseCode); } + //Element elem = parse(post.getResponseBodyAsStream()); - Document doc = DOMUtils.parseDocumentSimple(post.getResponseBodyAsStream()); + Document doc = DOMUtils.parseDocumentSimple(httpResp.getEntity().getContent()); return unpackFromSOAP(doc.getDocumentElement()); } catch(IOException e) { @@ -329,8 +342,24 @@ public class MISSimpleClient { } catch (Exception e) { throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); + } finally { + try { + if (httpclient != null) + httpclient.close(); + + if (httpResp != null) + httpResp.close(); + + + } catch (IOException e) { + Logger.error("HTTP-client or Response for MIS communication can NOT be closed!", e); + + } + + } + } private static Element packIntoSOAP(Element element) throws MISSimpleClientException { diff --git a/id/server/modules/moa-id-module-openID/pom.xml b/id/server/modules/moa-id-module-openID/pom.xml index 2bd3b6b4f..971751e9e 100644 --- a/id/server/modules/moa-id-module-openID/pom.xml +++ b/id/server/modules/moa-id-module-openID/pom.xml @@ -57,6 +57,11 @@ </exclusions> </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + </dependency> + <dependency> <groupId>com.googlecode.jsontoken</groupId> <artifactId>jsontoken</artifactId> |