I am using a rest service which requires authentication, Below curl command is used to achieve this
curl -v --insecure --request POST "https://ip:port/login" -d IDToken1="username" -d "password" --cookie-jar cookie.txt
After authentication it creates a cookie file.
Can someone helps in creating the corresponding rest client using java.
I have used
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client
.target("http://hilweb05:8080/login");
Form form = new Form().param("IDToken1", "username").param("IDToken2", "password");
Response jsonAnswer = target.request()
.accept(MediaType.APPLICATION_JSON).post(Entity.form(form));
if (jsonAnswer.getStatus() != 200) {
throw new RuntimeException("Not reachable "
+ jsonAnswer.getStatus());
}
List<SomeDataClass> matList = jsonAnswer.readEntity(new GenericType<List<SomeDataClass>>() {});
for (SomeDataClass m : matList) {
System.out.println(m.getF1() + " " + m.getF2() + " "
+ m.getF3());
}
But its not working
I switched to Apache http client, with the below piece of code I am able to get the cookie.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.SSLContext;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
public class ApacheHttpClient {
public static void main(String[] args) throws ClientProtocolException, IOException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial((chain, authType) -> true).build();
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, new String[]
{"SSLv2Hello", "SSLv3", "TLSv1","TLSv1.1", "TLSv1.2" }, null,
NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
try {
HttpPost httpPost = new HttpPost("url/login");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("IDToken1", name));
nvps.add(new BasicNameValuePair("IDToken2", password));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response2 = httpclient.execute(httpPost);
try {
System.out.println("Status -->>> "+ response2.getStatusLine().getStatusCode());
Header[] cookieInf = response2.getHeaders("Set-Cookie");
StringBuilder strBf = new StringBuilder();
for(Header header : cookieInf)
{
strBf.append(header.getValue());
}
System.out.println("Data is "+ strBf);
HttpEntity entity2 = response2.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity2);
} finally {
response2.close();
}
} finally {
httpclient.close();
}
}
}
Now I need to write the cookie in a text file, so I need help in parsing the cookie information so that it matches the cookie file generated by curl command.
With the below piece of code it works
public class JerseyClientPost {
public static void main(String[] args) {
try {
Client client = Client.create(configureClient());
final com.sun.jersey.api.client.WebResource webResource = client
.resource("https://wtc2e3enm.eng.mobilephone.net:443/login");
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("IDToken1", name);
formData.add("IDToken2", password);
try {
ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED)
.accept(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, formData);
String x = response.getEntity(String.class);
System.out.println("Response String is "+ x);
} catch (com.sun.jersey.api.client.ClientHandlerException che) {
che.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static ClientConfig configureClient() {
TrustManager[] certs = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
} };
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("SSL");
ctx.init(null, certs, new SecureRandom());
} catch (java.security.GeneralSecurityException ex) {
}
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
ClientConfig config = new DefaultClientConfig();
try {
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
new HTTPSProperties(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}, ctx));
} catch (Exception e) {
}
return config;
}
}
but I am not able to get the cookies from response, if I use curl I am able to get the cookie by using --cookie-jar argument. Can somebody help in getting the cookie
Related
I used httpclient 4.4 to send get and post request. and i just created a simpile wrapper of httpclient for easy use:
package com.u8.server.sdk;
import com.sun.net.httpserver.Headers;
import com.u8.server.log.Log;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.CookiePolicy;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by ant on 2015/10/12.
*/
public class UHttpAgent {
private int connectTimeout = 5000; //5s
private int socketTimeout = 5000; //5s
private int maxTotalConnections = 200;
private static UHttpAgent instance;
private CloseableHttpClient httpClient;
private UHttpAgent(){
}
public static UHttpAgent getInstance(){
if(instance == null){
instance = new UHttpAgent();
}
return instance;
}
public static UHttpAgent newInstance(){
return new UHttpAgent();
}
public String get(String url, Map params){
return get(url, null, params, "UTF-8");
}
public String post(String url, Map params){
return post(url, null, params, "UTF-8");
}
public String get(String url , Map headers, Map params, String encoding){
if(this.httpClient == null){
init();
}
String fullUrl = url;
String urlParams = parseGetParams(params, encoding);
if (urlParams != null)
{
if (url.contains("?"))
{
fullUrl = url + "&" + urlParams;
}
else
{
fullUrl = url + "?" + urlParams;
}
}
Log.d("the full url is "+ fullUrl);
HttpGet getReq = new HttpGet(fullUrl.trim());
getReq.setHeaders(parseHeaders(headers));
ResponseHandler responseHandler = new ResponseHandler() {
#Override
public String handleResponse(HttpResponse httpResponse) throws IOException {
HttpEntity entity = httpResponse.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
};
try {
String res = httpClient.execute(getReq, responseHandler);
return res;
} catch (Exception e) {
e.printStackTrace();
}finally {
getReq.releaseConnection();
}
return null;
}
public String post(String url, Map headers, Map params, String encoding){
List pairs = new ArrayList();
if(params != null){
for(String key : params.keySet()){
pairs.add(new BasicNameValuePair(key, params.get(key)));
}
}
return post(url, headers, new UrlEncodedFormEntity(pairs, Charset.forName(encoding)));
}
public String post(String url, Map headers, HttpEntity entity){
if(this.httpClient == null) {
init();
}
HttpPost httpPost = new HttpPost(url);
httpPost.setHeaders(parseHeaders(headers));
httpPost.setEntity(entity);
ResponseHandler responseHandler = new ResponseHandler() {
#Override
public String handleResponse(HttpResponse httpResponse) throws IOException {
HttpEntity entity = httpResponse.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
};
try {
String body = httpClient.execute(httpPost, responseHandler);
return body;
} catch (IOException e) {
e.printStackTrace();
}finally {
httpPost.releaseConnection();
}
return null;
}
private Header[] parseHeaders(Map headers){
if(null == headers || headers.isEmpty()){
return getDefaultHeaders();
}
Header[] hs = new BasicHeader[headers.size()];
int i = 0;
for(String key : headers.keySet()){
hs[i] = new BasicHeader(key, headers.get(key));
i++;
}
return hs;
}
private Header[] getDefaultHeaders(){
Header[] hs = new BasicHeader[2];
hs[0] = new BasicHeader("Content-Type", "application/x-www-form-urlencoded");
hs[1] = new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
return hs;
}
private String parseGetParams(Map data, String encoding){
if(data == null || data.size() keyItor = data.keySet().iterator();
while(keyItor.hasNext()){
String key = keyItor.next();
String val = data.get(key);
try {
result.append(key).append("=").append(URLEncoder.encode(val, encoding).replace("+", "%2B")).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return result.deleteCharAt(result.length() - 1).toString();
}
private void init(){
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout)
.setExpectContinueEnabled(true)
.setAuthenticationEnabled(true)
.build();
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
#Override
public boolean retryRequest(IOException e, int retryNum, HttpContext httpContext) {
if(retryNum >= 3){
return false;
}
if(e instanceof org.apache.http.NoHttpResponseException
|| e instanceof org.apache.http.client.ClientProtocolException
|| e instanceof java.net.SocketException){
return true;
}
return false;
}
};
try{
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
#Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry socketFactoryRegistry = RegistryBuilder.create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslFactory)
.build();
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
connMgr.setMaxTotal(maxTotalConnections);
connMgr.setDefaultMaxPerRoute((connMgr.getMaxTotal()));
HttpClientBuilder builder = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setSslcontext(sslContext)
.setConnectionManager(connMgr)
.setRetryHandler(retryHandler);
this.httpClient = builder.build();
}catch (Exception e){
e.printStackTrace();
}
}
public HttpClient getHttpClient(){
return this.httpClient;
}
public void destroy(){
if(this.httpClient != null){
try{
this.httpClient.close();
this.httpClient = null;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
when I use this class to send post request. something strange happened:
the first time, I send a post request to the server, it's ok
after a minutes, I send a same request to the server, it's ok too.
but after a few minutes, I send a same request, something wrong:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.http.impl.conn.LoggingOutputStream.write(LoggingOutputStream.java:77)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:126)
at org.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:138)
at org.apache.http.impl.io.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:146)
at org.apache.http.impl.BHttpConnectionBase.doFlush(BHttpConnectionBase.java:175)
at org.apache.http.impl.DefaultBHttpClientConnection.flush(DefaultBHttpClientConnection.java:185)
at org.apache.http.impl.conn.CPoolProxy.flush(CPoolProxy.java:177)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:215)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:122)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:220)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:164)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:139)
at com.u8.server.sdk.UHttpAgent.post(UHttpAgent.java:259)
at com.u8.server.sdk.UHttpAgent.post(UHttpAgent.java:147)
at com.u8.server.sdk.baidu.BaiduSDK.verify(BaiduSDK.java:30)
at com.u8.server.web.UserAction.getLoginToken(UserAction.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
but then , I still send a same request to the server, it's ok again.
Every time I tried according to the above steps, The same thing happened.
Anyone can help me ? Thanks a lot.
The peer of your client is the server. So "Connection reset by peer" means the server reset the socket. Reset means forceably closed.
This might be because of a bug in the server. If you also wrote the server or servlet (as will be the case for a custom protocol), you need to examine the behaviour of the server to examine the cause of this. The log files of the server might provide clues.
If the server has protection against bisbehaving or malicious clients, the server might have reset the socket because it has classified your client as misbehaving. If you implemented the client protocol code it might be because of a bug in your protocol implementation. If you are using third party code for handling the communication protocol you might still be misusing it; for example by sending excessively large requests. It is not uncommon for HTTP servers to protect themselves against denial of service attacks by imposing maximum lengths for header fields and bodies, and to require that clients send data at a reasonably fast rate (without pausing for long periods). Your client might have fallen foul of these protections.
I need to write Java SOAP client code to consume the web service upon the customer request. While i call java client code, i am getting 401 Unauthorized response code. However, when i call from postman, everything is fine. Here is the Java Client Code.
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.AuthCache;
import org.apache.http.impl.client.BasicAuthCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
import java.util.*;
#SpringBootApplication
public class DemoApplication implements CommandLineRunner {
Logger log = LoggerFactory.getLogger(DemoApplication.class);
static {
//disableSslVerification();
}
public static void disableSslVerification() {
try
{
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private final String REALM = "Restricted";
private final String SEPARATOR = ", ";
private final String QUOTE = "\"";
private final String NONCE = Long.toString(new Random().nextLong(), 36);
private String setAuthorizationHeader(String method, String username, String password,String nonce) throws AuthenticationException {
DigestScheme digestScheme = new DigestScheme();
Map<String,String> params = new HashMap<>();
String digest4 = DigestUtils.sha1Hex(username + ":" + REALM + ":" + password +new Date().getTime());
String digest2 = DigestUtils.md5Hex(method + ":" + "/");
params.put("uri","/soap/sp");
params.put("realm","Restricted");
params.put("nonce",nonce);
params.put("nc","01");
params.put("cnonce","0a458m12");
params.put("qop","auth");
params.put("methodname","POST");
params.put("algorithm","MD5");
String md5Hex = DigestScheme.createDigest("arbor","arbortt",params);
String header = DigestScheme.createDigestHeader("arbor",params,md5Hex);
String value = "Digest " + header;
return value;
}
public String calculateNonce() {
Date d = new Date();
SimpleDateFormat f = new SimpleDateFormat("yyyy:MM:dd:hh:mm:ss");
String fmtDate = f.format(d);
Random rand = new Random(100000);
Integer randomInt = rand.nextInt();
return DigestUtils.sha1Hex(fmtDate + randomInt.toString());
}
#Override
public void run(String... args) throws Exception {
System.setProperty("javax.net.ssl.trustStore","C:\\Users\\devuser\\Desktop\\keystorefile");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
disableSslVerification();
RestTemplate restTemplate = new RestTemplate();
String request = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:com.example.demo.PeakflowSP\">\n" +
" <soapenv:Header/>\n" +
" <soapenv:Body>\n" +
" <urn:getDosAlertSummaries soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" +
" <filter xsi:type=\"xsd:string\"></filter>\n" +
" <count xsi:type=\"xsd:unsignedInt\"></count>\n" +
" </urn:getDosAlertSummaries>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
headers.setContentType(MediaType.APPLICATION_XML);
String nonce = calculateNonce();
headers.add("ETag",nonce);
headers.add("Authorization",setAuthorizationHeader("getDosAlertSummaries","arbor","arbortt",nonce));
HttpEntity<String> entity = new HttpEntity<>(request, headers);
ResponseEntity<String> response = restTemplate.postForEntity("https://10.34.34.71/soap/sp", entity, String.class);
String str = response.getBody();
str = str.replace("xsi:type=\"ns1:DosAlertSummaryArray\"","");
str = str.replace("xsi:type=\"xsd:unsignedInt\"","");
str = str.replace("xsi:type=\"xsd:string\"","");
str = str.replace("xsi:type=\"xsd:boolean\"","");
str = str.replace("xsi:type=\"ns1:DosAlertSummary\"","");
str = str.replace("xsi:type=\"ns1:AlertDirection\"","");
str = str.replace("xsi:type=\"xsd:float\"","");
str = str.replace("xsi:type=\"xsd:dateTime\"","");
str = str.replace("xsi:type=\"ns1:AlertResource\"","");
str = str.replace("xsi:type=\"ns1:AlertManagedObject\"","");
str = str.replace("xsi:type=\"ns1:AlertImportance\"","");
str = str.replace("xsi:type=\"ns1:Annotation\"","");
str = str.replace("xsi:type=\"ns1:unitType\"","");
log.info(response.toString());
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(str));
xsr.nextTag();
xsr.nextTag();
xsr.nextTag();
xsr.nextTag();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StringWriter stringWriter = new StringWriter();
transformer.transform(new StAXSource(xsr), new StreamResult(stringWriter));
StringReader sr = new StringReader(stringWriter.toString());
JAXBContext jaxbContext = JAXBContext.newInstance(DosAlertSummaries.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DosAlertSummaries loginResult = (DosAlertSummaries) unmarshaller.unmarshal(sr);
}
}
Here is request log from program :
Digest username="arbor", realm="Restricted",
nonce="d90b71aa44b311113dd392e64e6d9347444d3b40",
uri="/soap/sp", qop="auth", algorithm="MD5", nc=01, cnonce="0a458m12",
response="297349367d0faa283a6649a004e104d1"
Postman request log :
Digest username="arbor", realm="Restricted",
nonce="Nf7oZOFzBQA=04e0c7c96bad6b7d2eabe2ec03831f55c13cde0d",
uri="/soap/sp", algorithm="MD5", qop=auth, nc=01, cnonce="0a458m12",
response="480da02481f50f76a7fbc82a63869e2e"
Request xml from postman :
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getDosAlertSummaries xmlns:ns1="urn:com.example.demo.PeakflowSP"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<filter xsi:type="xsd:string" />
<count xsi:type="xsd:unsignedInt">100</count>
</ns1:getDosAlertSummaries>
</soapenv:Body>
</soapenv:Envelope>
When i take the nonce value which postman created instead of calculateing in code, i get 200. Could anyone tell me where i am doing wrong ? Problem can be nonce value. If it is, how i can calculate nonce value correctly ?
Thanks
I have my okhttpclient android websocket and jetty stand-alone server given below. I have to enable strong security for the communication between the android client and jetty server. I am facing issue on client side which is given below.
Server Side
package com.wss.okhttp;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.servlet.ServletException;
import javax.websocket.DeploymentException;
import javax.websocket.server.ServerContainer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
public class JettySSLServer {
public static void main(String[] args) throws IOException {
JettyEndpoint endpoint = new JettyEndpoint();
Server webServer = new Server();
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
webServer.setHandler(context);
// --------------------SSL-Connection Start---------------------------//
KeyStore keyStore = null;
Certificate mPinnedCertificate = null;
try {
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, new char[] {});
mPinnedCertificate = readPinnedCertificate();
keyStore.setCertificateEntry("ca", mPinnedCertificate);
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SslContextFactory contextFactory = new SslContextFactory();
contextFactory.setIncludeProtocols("TLSv1.2");
contextFactory.setKeyStore(keyStore);
contextFactory.setKeyStorePassword("MIIEpAIBAAKCAQEAtzc9IK4U2YkfgASQ51v3IdjZUKABXw1RzUd+SxS8phI6O7Rb\r\n"
+ "RL+/KDQGPAtdrML2qDzaANIYa8rZ9jAyTnFAHpuykD8ByHf7RhogjPhJEvQDZkiX\r\n"
+ "r0hFS9A0ypqWn3fRWVXTREZTNGKgs0TQMNCY4Lm2H/lrgxNubaROn0KffLt+c5rK\r\n"
+ "7e3NXOcUUTP/tlkeC2JyHVIT8Cv2acaYJDD3PfHY5MSbvIORelVTp67eJkCSM+xF\r\n"
+ "spEi1SRuvRoBT+LMALNiIpi8nYBtNKlyDwmK2w38n11216g5DP3ipfZRHypk6048\r\n"
+ "vCO0qbgfwGfaep54twh94QJ4rjNi9X7f0F0qzCex7vmpJMpJ4gRl02mzni1DanOy\r\n"
+ "ExJB8ImpS3Il2jh2kVSbfLSg66UW33yAMKyCRCXypTSLgMGHetVDS+gHwcyFcE/M\r\n"
+ "nAY/k60CgYEA3ccY7AYSz10czJC0Y2ZPnw6NzESBNlWBgFIODQyKE5J2FKezJsR8\r\n"
+ "+LPRtEn+JeYI5+Q/jZZBR5qMXGaI+tprOlZKTSVcH4PQKOr7Ogd7v9leyH6zrfAe\r\n"
+ "k37acLaLtQE54tIyQVRLZW0dxzCiJ/tobJy+1f4TfWnpuRd4Y9xCnvMCgYEA03zT\r\n"
+ "aQLxW0ZBNbcz9ivDdbjy5kK2m1vA7Rq9LzawR0K9W05WOKUH7T1Ybp/idNTZfjKo\r\n"
+ "k+G2DV9ts/vQEL//3PthWo/FWZ8hsA5P1J+cT0RrwKKgWjCPNArp2l/T4vEdkGdM\r\n"
+ "GBbB6KZe5Wsn+HKPBszU35A8K2pD5PpebV0RGNcCgYBSEMmFFR5Cw2bTv7wwh/xw\r\n"
+ "lBcefj7+FxfrnvF6HKi/Y1P0grXFY7IG6atwtmyoI34qKQjnYLFZSLQlwP9xK/+/\r\n"
+ "v4yRDYEQXFtbuNAsAfbl4A61zES62X7G/4rfaH08Bm8gIr3b9NBNgNojCjkG6H4U\r\n"
+ "qs/nKbSWlOmaxzeSZD/2xwKBgQCJOlz/rc4ouLyFe1v3J0yMLbdHHBDbXD0iXRBW\r\n"
+ "+3iEtNSj03/0/3jWQtEH7y0FPDvoPDzQwEvd/4bym7nVtI/0txTjq5iV38D/OTop\r\n"
+ "sGu/r5jvhVbhTtMNJOu7LCUUA/p4Ad8JXnLyYEoBOXfVKZiPBAg5DKFOVoS5po/x\r\n"
+ "DMuUPwKBgQCa4cym/jJnK6r7h2xzE5bHLcniuud0F1DgCMkW/x026z4owpGtSCyK\r\n"
+ "BEQn/PY0rnSioRkcNjm5leGb1oOaFcT/QBgGhVpm09TyA/v8tj96pP631fYayzZh\r\n"
+ "lBEvszx6LOLEBbIioiXFtp1JhmWzkxvbuB114S3ChK+IKVrgZYTjvQ==");
contextFactory.setIncludeCipherSuites("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
contextFactory.setTrustAll(true);
SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(contextFactory,
org.eclipse.jetty.http.HttpVersion.HTTP_1_1.toString());
ServerConnector sslConnector = new ServerConnector(webServer, sslConnectionFactory);
sslConnector.setPort(8443);
webServer.addConnector(sslConnector);
ServerConnector wsConnector = new ServerConnector(webServer);
wsConnector.setPort(50055);
webServer.addConnector(wsConnector);
// --------------------SSL-Connection End---------------------------//
ServerContainer container;
try {
container = WebSocketServerContainerInitializer.configureContext(context);
container.addEndpoint(endpoint.getClass());
WebSocketServerContainerInitializer.configureContext(context);
webServer.start();
} catch (ServletException servEx) {
System.out.println(servEx.getMessage());
} catch (DeploymentException depEx) {
System.out.println(depEx.getMessage());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
private static Certificate readPinnedCertificate() throws CertificateException, IOException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new FileInputStream(System.getProperty("user.dir") + "/assets/va_cert.pem");
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
return ca;
}
}
Server Side Log
2018-04-26 18:33:51.049:INFO::main: Logging initialized #190ms
2018-04-26 18:33:51.229:INFO:oejs.Server:main: jetty-9.3.z-SNAPSHOT
2018-04-26 18:33:51.596:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler#4e7dc304{/,null,AVAILABLE}
2018-04-26 18:33:51.606:INFO:oejus.SslContextFactory:main: x509=X509#396f6598(ca,h=[],w=[]) for SslContextFactory#394e1a0f(null,null)
2018-04-26 18:33:51.630:INFO:oejs.ServerConnector:main: Started ServerConnector#458c1321{SSL,[ssl]}{0.0.0.0:8443}
2018-04-26 18:33:51.635:INFO:oejs.ServerConnector:main: Started ServerConnector#11438d26{HTTP/1.1,[http/1.1]}{0.0.0.0:50055}
2018-04-26 18:33:51.636:INFO:oejs.Server:main: Started #777ms
Client Side
package com.example.myapplication;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.TlsVersion;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class MainActivity extends AppCompatActivity {
private Button start;
private TextView output;
private OkHttpClient client;
private Certificate mPinnedCertificate;
private final class EchoWebSocketListener extends WebSocketListener {
private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
output("Sending----------");
webSocket.send("Hello, Friend");
webSocket.send("USA");
webSocket.send(ByteString.decodeHex("Hi"));
webSocket.close(NORMAL_CLOSURE_STATUS, "Goodbye !");
}
#Override
public void onMessage(WebSocket webSocket, String text) {
output("Receiving : " + text);
}
#Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
output("Receiving bytes : " + bytes.hex());
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
output("Closing : " + code + " / " + reason);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
output("Error : " + t.getMessage());
Log.i("Connection Error ",t.getMessage());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.start);
output = (TextView) findViewById(R.id.output);
prepareOkHttpClient();
// client = new OkHttpClient();
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
start();
}
});
}
private void start() {
Request request = new Request.Builder().url("wss://localhost:50055/sample").build();
EchoWebSocketListener listener = new EchoWebSocketListener();
WebSocket ws = client.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
}
private void output(final String txt) {
runOnUiThread(new Runnable() {
#Override
public void run() {
output.setText(output.getText().toString() + "\n\n" + txt);
}
});
}
private void prepareOkHttpClient() {
try {
ConnectionSpec wssSpecs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
.build();
mPinnedCertificate = readPinnedCertificate("va_cert.der");
// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, new char[]{});
keyStore.setCertificateEntry("ca", mPinnedCertificate);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = null;
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, tmf.getTrustManagers(), null);
Log.i("Protocol : ",sslContext.getProvider()+" **** " + sslContext.getProtocol());
TrustManager[] trustManagers = tmf.getTrustManagers();
client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(wssSpecs))
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
.connectTimeout(15000, TimeUnit.MILLISECONDS)
.build();
} catch (NoSuchAlgorithmException | CertificateException
| KeyStoreException | KeyManagementException | IOException e) {
Log.i("SSL Exception ",e.getMessage());
}
}
/**
* Reads SSL certificate from App Assets folder.
*
* #param certAssetName File name of the SSL certificate.
* #return Certificate object.
* #throws CertificateException Certificate is invalid exception.
* #throws IOException File does not exist.
*/
private Certificate readPinnedCertificate(final String certAssetName)
throws CertificateException, IOException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
AssetManager assManager = this.getApplicationContext().getAssets();
InputStream caInput = assManager.open(certAssetName);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
return ca;
}
}
Client Side Error
Connection Error: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)], supported protocols=[TLSv1, TLSv1.1, TLSv1.2]
Dont know how to fix this issue. Breaking my head for the past one week. Any help
new SslConnectionFactory(contextFactory,
org.eclipse.jetty.http.HttpVersion.HTTP_2.toString());
WebSocket over HTTP/2 doesn't exist (yet).
https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/
The concept of WebSocket over HTTP/2 is brand new, the draft specs have only been talked about in the past few months.
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-h2-websockets-01
I have combined client-certificate-with-com-sun-net-httpserver-httpsserver
with simple-java-https-server but I always get the error message
SSL-Peer could not be verified.
I call setWantClientAuth(true) and verify Authentification by calling
Certificate[] peerCerts = pHttpsExchange.getSSLSession().getPeerCertificates();
The server is running with JDK 1.8 and the client is running on Android. The server Code is:
package de.org.vnetz;
import java.io.*;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import com.sun.net.httpserver.*;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import javax.net.ssl.SSLContext;
import javax.security.auth.x500.X500Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class clsHTTPSServer {
final static String SERVER_PWD = "xxxxxx";
final static String KST_SERVER = "server.jks";
final static String TST_SERVER = "servertrust.jks";
private static final int PORT = 9999;
public static class MyHandler implements HttpHandler {
// whether to use client cert authentication
private final boolean useClientCertAuth = true;
private List<LdapName> allowedPrincipals = new ArrayList<LdapName>();
private final boolean extendedClientCheck = true;
private static final String CLIENTAUTH_OID = "1.3.6.1.5.5.7.3.2";
#Override
public void handle(HttpExchange t) throws IOException {
String response = "Hallo Natalie!";
HttpsExchange httpsExchange = (HttpsExchange) t;
boolean auth;
try
{
checkAuthentication(httpsExchange);
auth = true;
}
catch (Exception ex)
{
response = ex.getMessage();
auth = false;
}
boolean res = httpsExchange.getSSLSession().isValid();
if (res) {
String qry = httpsExchange.getRequestURI().getQuery();
if (qry!=null && qry.startsWith("qry=")) {
httpsExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
httpsExchange.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
else
{
httpsExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
httpsExchange.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write((response + " no query!").getBytes());
os.close();
}
}
}
// Verify https certs if its Https request and we have SSL auth enabled. Will be called before
// handling the request
protected void checkAuthentication(HttpExchange pHttpExchange) throws SecurityException {
// Cast will always work since this handler is only used for Http
HttpsExchange httpsExchange = (HttpsExchange) pHttpExchange;
if (useClientCertAuth) {
checkCertForClientUsage(httpsExchange);
checkCertForAllowedPrincipals(httpsExchange);
}
}
// Check the cert's principal against the list of given allowedPrincipals.
// If no allowedPrincipals are given than every principal is allowed.
// If an empty list as allowedPrincipals is given, no one is allowed to access
private void checkCertForClientUsage(HttpsExchange pHttpsExchange) {
try {
String host = pHttpsExchange.getSSLSession().getPeerHost();
//Principal p = pHttpsExchange.getSSLSession().getPeerPrincipal();
String pr = pHttpsExchange.getSSLSession().getProtocol();
Certificate[] peerCerts = pHttpsExchange.getSSLSession().getPeerCertificates();
if (peerCerts != null && peerCerts.length > 0) {
X509Certificate clientCert = (X509Certificate) peerCerts[0];
// We required that the extended key usage must be present if we are using
// client cert authentication
if (extendedClientCheck &&
(clientCert.getExtendedKeyUsage() == null || !clientCert.getExtendedKeyUsage().contains(CLIENTAUTH_OID))) {
throw new SecurityException("No extended key usage available");
}
}
} catch (ClassCastException e) {
throw new SecurityException("No X509 client certificate");
} catch (CertificateParsingException e) {
throw new SecurityException("Can't parse client cert");
} catch (SSLPeerUnverifiedException e) {
throw new SecurityException("SSL Peer couldn't be verified");
}
}
private void checkCertForAllowedPrincipals(HttpsExchange pHttpsExchange) {
if (allowedPrincipals != null) {
X500Principal certPrincipal;
try {
certPrincipal = (X500Principal) pHttpsExchange.getSSLSession().getPeerPrincipal();
Set<Rdn> certPrincipalRdns = getPrincipalRdns(certPrincipal);
for (LdapName principal : allowedPrincipals) {
for (Rdn rdn : principal.getRdns()) {
if (!certPrincipalRdns.contains(rdn)) {
throw new SecurityException("Principal " + certPrincipal + " not allowed");
}
}
}
} catch (SSLPeerUnverifiedException e) {
throw new SecurityException("SSLPeer unverified");
} catch (ClassCastException e) {
throw new SecurityException("Internal: Invalid Principal class provided " + e);
}
}
}
private Set<Rdn> getPrincipalRdns(X500Principal principal) {
try {
LdapName certAsLdapName =new LdapName(principal.getName());
return new HashSet<Rdn>(certAsLdapName.getRdns());
} catch (InvalidNameException e) {
throw new SecurityException("Cannot parse '" + principal + "' as LDAP name");
}
}
}
/**
* #param args
*/
public static void main(String[] args) throws Exception {
try {
// setup the socket address
InetSocketAddress address = new InetSocketAddress(PORT);
// initialise the HTTPS server
HttpsServer httpsServer = HttpsServer.create(address, 0);
SSLContext sslContext = SSLContext.getInstance("TLS");
// initialise the keystore
// char[] password = "password".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream(KST_SERVER);// ("testkey.jks");
ks.load(fis, SERVER_PWD.toCharArray());// password);
// setup the key manager factory
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, SERVER_PWD.toCharArray());
// setup the trust manager factory
// TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
// tmf.init(ks);
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(new FileInputStream(TST_SERVER), SERVER_PWD.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
// setup the HTTPS context and parameters
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLParameters sslp = sslContext.getSupportedSSLParameters();
//sslp.setNeedClientAuth(true);
sslp.setWantClientAuth(true);
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
public void configure(HttpsParameters params) {
try {
// initialise the SSL context
SSLContext c = SSLContext.getDefault();
SSLEngine engine = c.createSSLEngine();
//params.setNeedClientAuth(true);
params.setWantClientAuth(true);
params.setCipherSuites(engine.getEnabledCipherSuites());
params.setProtocols(engine.getEnabledProtocols());
// get the default parameters
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
SSLParameters sslParams = sslContext.getDefaultSSLParameters();
//sslParams.setNeedClientAuth(true);
sslParams.setWantClientAuth(true);
params.setSSLParameters(defaultSSLParameters);
} catch (Exception ex) {
System.out.println("Failed to create HTTPS port");
}
}
});
httpsServer.createContext("/test", new MyHandler());
httpsServer.setExecutor(
new ThreadPoolExecutor(4, 80, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000))); // creates
// a
// default
// executor
httpsServer.start();
} catch (Exception exception) {
System.out.println("Failed to create HTTPS server on port " + 62112 + " of localhost");
exception.printStackTrace();
}
}
}
The client code is:
package vnetz.de.org.vnetz;
import android.content.Context;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class clsHTTPS {
private static final String MYURL = "https://localhost:9999/test?qry=test";
static String NO_KEYSTORE = "";
static String UNAUTH_KEYSTORE = "unauthclient.bks"; // Doesn't exist in server trust store, should fail authentication.
static String AUTH_KEYSTORE = "authclient.bks"; // Exists in server trust store, should pass authentication.
static String TRUSTSTORE = "clienttrust.bks";
static String CLIENT_PWD = "xxxxxx";
private static Context context = null;
public clsHTTPS(Context context) {
this.context = context;
}
public static void main(String[] args) throws Exception {
}
public String connect(String jksFile) {
try {
String https_url = MYURL;
URL url;
url = new URL(https_url);
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(getSSLFactory(jksFile));
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setUseCaches(false);
// Print response
//SSLContext context = SSLContext.getInstance("TLS");
//context.init(null, new X509TrustManager[]{new NullX509TrustManager()}, new SecureRandom());
//HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
BufferedReader bir = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sbline = new StringBuilder();
String line;
while ((line = bir.readLine()) != null) {
System.out.println(line);
sbline.append(line);
}
bir.close();
conn.disconnect();
return sbline.toString();
} catch (SSLHandshakeException | SocketException e) {
System.out.println(e.getMessage());
System.out.println("");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static SSLSocketFactory getSSLFactory(String jksFile) throws Exception {
// Create key store
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
KeyManager[] kmfs = null;
if (jksFile.length() > 0) {
keyStore.load(context.getAssets().open(jksFile), CLIENT_PWD.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, CLIENT_PWD.toCharArray());
kmfs = kmf.getKeyManagers();
}
// create trust store (validates the self-signed server!)
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(context.getAssets().open(TRUSTSTORE), CLIENT_PWD.toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmfs, trustFactory.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
private class NullHostNameVerifier implements HostnameVerifier
{
#Override
public boolean verify(String s, SSLSession sslSession)
{
return s.equalsIgnoreCase("localhost");
}
}
private class NullX509TrustManager implements X509TrustManager
{
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
#Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}
}
'Peer not verified' in a server means that the client didn't send a certificate, which probably means that its signer isn't in your server's truststore. When the server requests the client certificate, it supplies a list of acceptable signers, and the client must not send a certificate that isn't signed by one of those.
Or else the server didn't ask for a client certificate at all. Doesn't apply in this case.
In your case it would be a lot simpler to use needClientAuth, as that will just fail the handshake without you having to get as a far as getPeerCertificates().
NB:
The SSLSession is valid, otherwise you wouldn't have an SSL connection. The only way it becomes invalid is if you call invalidate(), which causes a full re-handshake on the next I/O. You're testing the wrong thing.
Checking for allowed principals is authorization, not authentication.
I used httpclient 4.4 to send get and post request. and i just created a simpile wrapper of httpclient for easy use:
package com.u8.server.sdk;
import com.sun.net.httpserver.Headers;
import com.u8.server.log.Log;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.CookiePolicy;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by ant on 2015/10/12.
*/
public class UHttpAgent {
private int connectTimeout = 5000; //5s
private int socketTimeout = 5000; //5s
private int maxTotalConnections = 200;
private static UHttpAgent instance;
private CloseableHttpClient httpClient;
private UHttpAgent(){
}
public static UHttpAgent getInstance(){
if(instance == null){
instance = new UHttpAgent();
}
return instance;
}
public static UHttpAgent newInstance(){
return new UHttpAgent();
}
public String get(String url, Map params){
return get(url, null, params, "UTF-8");
}
public String post(String url, Map params){
return post(url, null, params, "UTF-8");
}
public String get(String url , Map headers, Map params, String encoding){
if(this.httpClient == null){
init();
}
String fullUrl = url;
String urlParams = parseGetParams(params, encoding);
if (urlParams != null)
{
if (url.contains("?"))
{
fullUrl = url + "&" + urlParams;
}
else
{
fullUrl = url + "?" + urlParams;
}
}
Log.d("the full url is "+ fullUrl);
HttpGet getReq = new HttpGet(fullUrl.trim());
getReq.setHeaders(parseHeaders(headers));
ResponseHandler responseHandler = new ResponseHandler() {
#Override
public String handleResponse(HttpResponse httpResponse) throws IOException {
HttpEntity entity = httpResponse.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
};
try {
String res = httpClient.execute(getReq, responseHandler);
return res;
} catch (Exception e) {
e.printStackTrace();
}finally {
getReq.releaseConnection();
}
return null;
}
public String post(String url, Map headers, Map params, String encoding){
List pairs = new ArrayList();
if(params != null){
for(String key : params.keySet()){
pairs.add(new BasicNameValuePair(key, params.get(key)));
}
}
return post(url, headers, new UrlEncodedFormEntity(pairs, Charset.forName(encoding)));
}
public String post(String url, Map headers, HttpEntity entity){
if(this.httpClient == null) {
init();
}
HttpPost httpPost = new HttpPost(url);
httpPost.setHeaders(parseHeaders(headers));
httpPost.setEntity(entity);
ResponseHandler responseHandler = new ResponseHandler() {
#Override
public String handleResponse(HttpResponse httpResponse) throws IOException {
HttpEntity entity = httpResponse.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
};
try {
String body = httpClient.execute(httpPost, responseHandler);
return body;
} catch (IOException e) {
e.printStackTrace();
}finally {
httpPost.releaseConnection();
}
return null;
}
private Header[] parseHeaders(Map headers){
if(null == headers || headers.isEmpty()){
return getDefaultHeaders();
}
Header[] hs = new BasicHeader[headers.size()];
int i = 0;
for(String key : headers.keySet()){
hs[i] = new BasicHeader(key, headers.get(key));
i++;
}
return hs;
}
private Header[] getDefaultHeaders(){
Header[] hs = new BasicHeader[2];
hs[0] = new BasicHeader("Content-Type", "application/x-www-form-urlencoded");
hs[1] = new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
return hs;
}
private String parseGetParams(Map data, String encoding){
if(data == null || data.size() keyItor = data.keySet().iterator();
while(keyItor.hasNext()){
String key = keyItor.next();
String val = data.get(key);
try {
result.append(key).append("=").append(URLEncoder.encode(val, encoding).replace("+", "%2B")).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return result.deleteCharAt(result.length() - 1).toString();
}
private void init(){
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout)
.setExpectContinueEnabled(true)
.setAuthenticationEnabled(true)
.build();
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
#Override
public boolean retryRequest(IOException e, int retryNum, HttpContext httpContext) {
if(retryNum >= 3){
return false;
}
if(e instanceof org.apache.http.NoHttpResponseException
|| e instanceof org.apache.http.client.ClientProtocolException
|| e instanceof java.net.SocketException){
return true;
}
return false;
}
};
try{
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
#Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry socketFactoryRegistry = RegistryBuilder.create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslFactory)
.build();
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
connMgr.setMaxTotal(maxTotalConnections);
connMgr.setDefaultMaxPerRoute((connMgr.getMaxTotal()));
HttpClientBuilder builder = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setSslcontext(sslContext)
.setConnectionManager(connMgr)
.setRetryHandler(retryHandler);
this.httpClient = builder.build();
}catch (Exception e){
e.printStackTrace();
}
}
public HttpClient getHttpClient(){
return this.httpClient;
}
public void destroy(){
if(this.httpClient != null){
try{
this.httpClient.close();
this.httpClient = null;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
when I use this class to send post request. something strange happened:
the first time, I send a post request to the server, it's ok
after a minutes, I send a same request to the server, it's ok too.
but after a few minutes, I send a same request, something wrong:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.http.impl.conn.LoggingOutputStream.write(LoggingOutputStream.java:77)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:126)
at org.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:138)
at org.apache.http.impl.io.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:146)
at org.apache.http.impl.BHttpConnectionBase.doFlush(BHttpConnectionBase.java:175)
at org.apache.http.impl.DefaultBHttpClientConnection.flush(DefaultBHttpClientConnection.java:185)
at org.apache.http.impl.conn.CPoolProxy.flush(CPoolProxy.java:177)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:215)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:122)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:220)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:164)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:139)
at com.u8.server.sdk.UHttpAgent.post(UHttpAgent.java:259)
at com.u8.server.sdk.UHttpAgent.post(UHttpAgent.java:147)
at com.u8.server.sdk.baidu.BaiduSDK.verify(BaiduSDK.java:30)
at com.u8.server.web.UserAction.getLoginToken(UserAction.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
but then , I still send a same request to the server, it's ok again.
Every time I tried according to the above steps, The same thing happened.
Anyone can help me ? Thanks a lot.
The peer of your client is the server. So "Connection reset by peer" means the server reset the socket. Reset means forceably closed.
This might be because of a bug in the server. If you also wrote the server or servlet (as will be the case for a custom protocol), you need to examine the behaviour of the server to examine the cause of this. The log files of the server might provide clues.
If the server has protection against bisbehaving or malicious clients, the server might have reset the socket because it has classified your client as misbehaving. If you implemented the client protocol code it might be because of a bug in your protocol implementation. If you are using third party code for handling the communication protocol you might still be misusing it; for example by sending excessively large requests. It is not uncommon for HTTP servers to protect themselves against denial of service attacks by imposing maximum lengths for header fields and bodies, and to require that clients send data at a reasonably fast rate (without pausing for long periods). Your client might have fallen foul of these protections.