Send soap message with java - java

I am experiencing a problem while trying to send a soap request on a https server.
I seems that I am not sending any certificate but I don't know how to do that. I get an SSL handshake error.
Here is my source code. Sorry for the mess .... :)
public class Sign {
static String myToken = "";
static SOAPMessage signedRequest = null;
static SOAPEnvelope soapEnvelope = null;
static String url = "";
static String fileToSend = "";
static String receiptDir = "";
static String jksKey = "";
static String keyPwd = "";
static String privKeyAlias = "";
static TrustManagerFactory tmf = null;
public static void main(String[] args) throws Exception {
try {
url = args[0];
System.out.println(url);
fileToSend = args[1];
System.out.println(fileToSend);
receiptDir = args[2];
System.out.println(receiptDir);
jksKey = args[3];
System.out.println(jksKey);
keyPwd = args[4];
System.out.println(keyPwd);
privKeyAlias = args[5];
System.out.println(privKeyAlias);
} catch (Exception e) {
System.out.println("Paramètres incorrects !");
e.printStackTrace();
}
// Timestamp to use
SimpleDateFormat formater = null;
Date aujourdhui = new Date();
formater = new SimpleDateFormat("yyyyMMddHHmmss");
myToken = formater.format(aujourdhui);
// myToken = "20150112202835";
////////////////////////////
// Constructing the message
////////////////////////////
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
soapEnvelope = soapPart.getEnvelope();
soapEnvelope.removeNamespaceDeclaration(soapEnvelope.getPrefix());
soapEnvelope.setPrefix("soapenv");
soapEnvelope.addNamespaceDeclaration("tem", "http://tempuri.org/");
soapEnvelope.addNamespaceDeclaration("elc",
"http://schemas.datacontract.org/2004/07/ZIRE.Match.Presentation.WebService");
SOAPHeader soapHeader = soapEnvelope.getHeader();
soapHeader.setPrefix("soapenv");
Name nameSecurity = soapEnvelope.createName("Security", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement soapSecurity = soapHeader.addChildElement(nameSecurity);
soapSecurity.addNamespaceDeclaration("wsu",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
Name nameBinSec = soapEnvelope.createName("BinarySecurityToken", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement soapBinSec = soapSecurity.addChildElement(nameBinSec);
soapBinSec.setAttribute("EncodingType",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
soapBinSec.setAttribute("ValueType",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
soapBinSec.setAttribute("wsu:Id", "X509-" + myToken);
SOAPBody soapBody = soapEnvelope.getBody();
soapBody.setPrefix("soapenv");
soapBody.addAttribute(
soapEnvelope.createName("id", "wsu",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"),
"id-" + myToken);
soapBody.setIdAttribute("wsu:id", true);
////////////////////////////
// Adding the real content
////////////////////////////
// The real payload new String(readAllBytes(get("test.txt")))
String xmlValue = "<![CDATA[" + readFile(fileToSend, StandardCharsets.UTF_8) + "]]>";
// String xmlValue = "<![CDATA[" + new String(readAllBytes(get(fileToSend))) + "]]>";
// System.out.println(xmlValue);
QName sendMessage = new QName("tem:SendMessage");
QName request = new QName("tem:request");
QName xmldata = new QName("elc:XmlData");
SOAPElement sendMessageNode = soapBody.addChildElement(sendMessage);
SOAPElement requestNode = soapBody.addChildElement(request);
SOAPElement xmldataNode = soapBody.addChildElement(xmldata);
xmldataNode.addTextNode(xmlValue);
requestNode.addChildElement(xmldataNode);
sendMessageNode.addChildElement(requestNode);
Source source = soapPart.getContent();
////////////////////////////////////////////////////////
// Sending the request to the signing function
////////////////////////////////////////////////////////
Node root = ((DOMSource) source).getNode();
signedRequest = addSignature(root.getFirstChild().getOwnerDocument());
////////////////////////////////////////////////////////
// SSL mode configuration
////////////////////////////////////////////////////////
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// Using null here initialises the TMF with the default trust store.
tmf.init((KeyStore) null);
// Get hold of the default trust manager
X509TrustManager defaultTm = null;
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
defaultTm = (X509TrustManager) tm;
break;
}
}
FileInputStream myKeys = new FileInputStream("D:\\ZIRE\\MesCertificats\\myTrustStore");
// Do the same with your trust store this time
// Adapt how you load the keystore to your needs
KeyStore myTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
myTrustStore.load(myKeys, "zire2016".toCharArray());
myKeys.close();
tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(myTrustStore);
// Get hold of the default trust manager
X509TrustManager myTm = null;
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
myTm = (X509TrustManager) tm;
break;
}
}
// Wrap it in your own class.
final X509TrustManager finalDefaultTm = defaultTm;
final X509TrustManager finalMyTm = myTm;
X509TrustManager customTm = new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
// If you're planning to use client-cert auth,
// merge results from "defaultTm" and "myTm".
return finalDefaultTm.getAcceptedIssuers();
}
#Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
try {
finalMyTm.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
// This will throw another CertificateException if this fails too.
finalDefaultTm.checkServerTrusted(chain, authType);
}
}
#Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
// If you're planning to use client-cert auth,
// do the same as checking the server.
finalDefaultTm.checkClientTrusted(chain, authType);
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { customTm }, null);
// You don't have to set this as the default context,
// it depends on the library you're using.
SSLContext.setDefault(sslContext);
////////////////////////////////////////////////////////
// Sending the request to the receiver
////////////////////////////////////////////////////////
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
// System.setProperty("javax.net.ssl.trustStore", "D:\\ZIRE\\MesCertificats\\myTrustStore" );
// System.setProperty("javax.net.ssl.trustStorePassword", "zire2016");
// System.setProperty("java.net.useSystemProxies", "true");
// SOAPMessage soapResponse = soapConnection.call(signedRequest, url);
// doTrustToCertificates();
SOAPMessage soapResponse = sendMessage(signedRequest, url);
////////////////////////////////////////////////////////
// Processing the response
////////////////////////////////////////////////////////
// Cleaning of the response
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapResponse.writeTo(out);
String strMsg = new String(out.toByteArray());
int d = strMsg.indexOf("<s:Envelope");
int f = strMsg.indexOf("</s:Envelope>") + 13;
String strMsg2 = strMsg.substring(d, f);
// System.out.println(strMsg2);
// Writting of the response on the server
// PrintWriter printWriter = new PrintWriter("D:\\ZIRE\\Result.xml");
// fileToSend
// String receiptFileName = (new File(fileToSend)).getParent() + "Receipt_" + (new File(fileToSend)).getName();
// System.out.println(receiptFileName);
// Writing the response
String receiptFileName = receiptDir + "Receipt_" + (new File(fileToSend)).getName();
System.out.println(receiptFileName);
PrintWriter printWriter = new PrintWriter( receiptFileName );
printWriter.println(strMsg2);
printWriter.close();
soapConnection.close();
}
public static SOAPMessage addSignature(Document contenu)
throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException,
IOException, InvalidAlgorithmParameterException, InstantiationException, IllegalAccessException,
ClassNotFoundException, KeyException, SAXException, ParserConfigurationException, MarshalException,
XMLSignatureException, TransformerException, InvalidKeySpecException, XMLSecurityException, SOAPException {
// Chargement des clés
// FileInputStream is = new FileInputStream("D:\\ZIRE\\Step 1\\mock\\NewJKS.jks");
FileInputStream is = new FileInputStream(jksKey);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, null);
// tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); // PKIX
// tmf.init(keystore);
// Enumeration<String> myEnum = keystore.aliases();
// for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements();) {
// String newAlias = e.nextElement();
// System.out.println(newAlias);
// if (newAlias != "wsgbit" ) {
// System.out.println(keystore.getCertificate(newAlias));
// }
// }
// Recup clé privée
// String alias = "wsgbit";
String alias = privKeyAlias;
// Key key = keystore.getKey(alias, "password".toCharArray());
Key key = keystore.getKey(alias, keyPwd.toCharArray());
KeyPair kp = null;
Certificate cert = null;
if (key instanceof PrivateKey) {
// Get certificate of public key
cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
kp = new KeyPair(publicKey, (PrivateKey) key);
}
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = contenu;
// dumpDocument(doc);
// MAJ du champ wsse:BinarySecurityToken
Element elt = doc.getDocumentElement();
Node myBinSecElt = (Node) (elt.getElementsByTagName("wsse:BinarySecurityToken")).item(0);
myBinSecElt.setTextContent(Utf8.decode(Base64.encode(cert.getEncoded())));
// Debut
org.apache.xml.security.Init.init();
Node mySecElt = (Node) (elt.getElementsByTagName("wsse:Security")).item(0);
org.apache.xml.security.signature.XMLSignature xmlSignature = new org.apache.xml.security.signature.XMLSignature(
doc, "", org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
"http://www.w3.org/2001/10/xml-exc-c14n#");
Element eltSign = xmlSignature.getElement();
eltSign.setAttribute("Id", "SIG-" + myToken);
mySecElt.appendChild(eltSign);
Transforms transforms = new Transforms(doc);
transforms.addTransform("http://www.w3.org/2001/10/xml-exc-c14n#");
xmlSignature.addDocument("#id-" + myToken, transforms, Constants.ALGO_ID_DIGEST_SHA1);
SOAPElement myCanonElt = (SOAPElement) (elt.getElementsByTagName("ds:CanonicalizationMethod")).item(0);
InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(doc, "elc soapenv tem");
myCanonElt.appendChild(inclusiveNamespaces.getElement());
SOAPElement mySoapTransform = (SOAPElement) (elt.getElementsByTagName("ds:Transform")).item(0);
InclusiveNamespaces inclusiveNamespaces2 = new InclusiveNamespaces(doc, "elc tem");
mySoapTransform.appendChild(inclusiveNamespaces2.getElement());
// Ajustements
// SOAPElement myCanonElt = (SOAPElement)
// (elt.getElementsByTagName("ds:CanonicalizationMethod")).item(0);
// myCanonElt.setAttribute("Algorithm",
// "http://www.w3.org/2001/10/xml-exc-c14n#");
// Name nameInclusiveNamespaces =
// soapEnvelope.createName("InclusiveNamespaces", "ec",
// "http://www.w3.org/2001/10/xml-exc-c14n#");
// SOAPElement soapInclusiveNamespaces =
// myCanonElt.addChildElement(nameInclusiveNamespaces);
// soapInclusiveNamespaces.setAttribute("PrefixList", "elc soapenv
// tem");
//
// SOAPElement mySoapTransform = (SOAPElement)
// (elt.getElementsByTagName("ds:Transform")).item(0);
// Name nameInclusiveNamespaces2 =
// soapEnvelope.createName("InclusiveNamespaces", "ec",
// "http://www.w3.org/2001/10/xml-exc-c14n#");
// SOAPElement soapInclusiveNamespaces2 =
// mySoapTransform.addChildElement(nameInclusiveNamespaces2);
// soapInclusiveNamespaces2.setAttribute("PrefixList", "elc tem");
//
Name nameKeyInfo = soapEnvelope.createName("KeyInfo", "ds", "http://www.w3.org/2000/09/xmldsig#");
SOAPElement mySoapSign = (SOAPElement) (elt.getElementsByTagName("ds:Signature")).item(0);
SOAPElement soapKeyInfo = mySoapSign.addChildElement(nameKeyInfo);
soapKeyInfo.setAttribute("Id", "KI-" + myToken);
Name nameSecToken = soapEnvelope.createName("SecurityTokenReference", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement soapSecToken = soapKeyInfo.addChildElement(nameSecToken);
soapSecToken.setAttribute("wsu:Id", "STR-" + myToken);
Name nameRef = soapEnvelope.createName("Reference", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement soapNameRef = soapSecToken.addChildElement(nameRef);
soapNameRef.setAttribute("URI", "#X509-" + myToken);
soapNameRef.setAttribute("ValueType",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
xmlSignature.sign(key);
// xmlSignature.sign(key);
// dumpDocument(doc);
// String xml = new XMLOutputter().outputString(doc);
// Ecriture du String represantant la requete signée
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
// transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
// transformer.setOutputProperty(OutputKeys.METHOD, "xml");
// transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc), new StreamResult(sw));
// String xml = sw.toString(); System.out.println(">>>" + xml + "<<<");
InputStream inputStream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));// new
// InputStream(xml);
MessageFactory messageFactory = MessageFactory.newInstance();
return messageFactory.createMessage(null, inputStream);
// Ecriture dans un fichier
// Transformer transformer =
// TransformerFactory.newInstance().newTransformer();
// Result output = new StreamResult(new
// FileOutputStream("D:\\ZIRE\\mySignedFile2.xml"));
// Source input = new DOMSource(doc);
// transformer.transform(input, output);
}
public static String convertToString(Document document) throws TransformerException {
DOMSource domSource = new DOMSource(document);
StringWriter sw = new StringWriter();
Result result = new StreamResult(sw);
// create an instance of TransformerFactory
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
trans.transform(domSource, result);
return sw.toString();
}
private static void dumpDocument(Node root) throws TransformerException {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(root), new StreamResult(System.out));
}
private static Element getFirstChildElement(Node node) {
Node child = node.getFirstChild();
while ((child != null) && (child.getNodeType() != Node.ELEMENT_NODE)) {
child = child.getNextSibling();
}
return (Element) child;
}
public static Element getNextSiblingElement(Node node) {
Node sibling = node.getNextSibling();
while ((sibling != null) && (sibling.getNodeType() != Node.ELEMENT_NODE)) {
sibling = sibling.getNextSibling();
}
return (Element) sibling;
}
static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
static public SOAPMessage sendMessage(SOAPMessage message, String endPoint) throws SOAPException, IOException {
SOAPMessage result = null;
if (endPoint != null && message != null) {
URL url;
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = null;
try {
connection = scf.createConnection(); //point-to-point connection
url = new URL(endPoint);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.connect();
result = connection.call(message, url);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SOAPException soape) {
System.out.print("Can't close SOAPConnection:" + soape);
}
}
}
}
return result;
}
static public void doTrustToCertificates() throws Exception {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
return;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
return;
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
}
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
}
Wireshark has shown me I am not sending my certificate though I am using JVM params like -Djavax.net.ssl.keyStore=...
But I am wondering how can the JVM know where is my certificate as I can have many certificates in a jks file ???

if you want to call a https-site you do not have to send a cert by default. the server has to send and your client will eval it (by uri, expiry-date, cert-chain, ...). if the cert is valid your http-client should accept it by default.
in other cases you can import the cert of the server to your local keystore (jks) and the client will accept it, cause you never would import "untrusted" certs to your local keystore.
or you implement a code like "who cares the cert? just do it!" (link: telling java to accept self-signed ssl certificate).
but this is not supposed to be used in public/prod environment (like internet)

Related

Android studio "Wrote stack traces to tombstoned" when connecting to server

I'm trying to log in to my server from my app with self-signed certificate. When I try to log in I get this error:
"Thread[6,tid=17486,WaitingInMainSignalCatcherLoop,Thread*=0xb4000074d0ac6570,peer=0x147c0000,"Signal Catcher"]: reacting to signal 3 "
"Wrote stack traces to tombstoned."
What could be the cause of that? I searched this error and found a few solutions but none worked.
Here is my code:
public class Connection extends AsyncTask{
#Override
protected Object doInBackground(Object[] objects) {
try {
Connect();
} catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException | NullPointerException e) {
e.printStackTrace();
ServerDirectActivity.response = true;
ServerDirectActivity.responseMsg = String.valueOf(e);
}
return null;
}
}
private void Connect() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException, NullPointerException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { #Override public boolean verify(String hostname, SSLSession session) { return true; } });
InputStream caInput = ServerDirectActivity.getmInstanceActivity().getAssets().open("client.csr");
Certificate ca = null;
try{
ca = cf.generateCertificate(caInput);
}catch (CertificateException e){
e.printStackTrace();
}finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL url = new URL(serverIP);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
final String basicAuth = "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
urlConnection.setRequestProperty("Authorization", basicAuth);
urlConnection.setSSLSocketFactory(context.getSocketFactory());
System.out.println(urlConnection.getResponseMessage());
System.out.println(urlConnection.getResponseCode());
if (urlConnection.getResponseCode() == 200){
InputStream in = urlConnection.getInputStream();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
while ((line = reader.readLine()) != null){
out.append(line);
}
System.out.println(out);
}
ServerDirectActivity.response = true;
ServerDirectActivity.responseMsg = String.valueOf(urlConnection.getResponseCode());
}
}

Java webapp with two URL connections: basic auth and cert auth

I have a java webapp which uses this class for connecting to server by using basic auth and cert. It works fine separately (without creating other url connections):
public void connectCert(String jsonParams) {
try {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream("d:\\certs\\api\\xx.p12"), "W*53as_G".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, "W*53as_G".toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("c:\\jdk1.8.0_51\\jre\\lib\\security\\cacerts"), "changeit".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kms, tms, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL("https://apis2s.ee/test");
HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();
urlConn.setRequestProperty("Authorization", "Basic " + Base64.encode("andrey:pass_1".getBytes()));
urlConn.setUseCaches(false);
urlConn.setAllowUserInteraction(true);
urlConn.setRequestProperty("Pragma", "no-cache");
urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
urlConn.setRequestProperty("Content-length", Integer.toString(jsonParams.length()));
urlConn.setDoOutput(true);
urlConn.setRequestProperty("Content-Length", Integer.toString(jsonParams.length()));
PrintStream out = new PrintStream(urlConn.getOutputStream());
out.print(jsonParams);
out.flush();
out.close();
StringBuilder builder = new StringBuilder();
int responseCode = urlConn.getResponseCode();
builder.append(responseCode).append(" ").append(urlConn.getResponseMessage()).append("\n");
InputStream inputStream = null;
if (responseCode == 200) inputStream = urlConn.getInputStream();
else inputStream = urlConn.getErrorStream();//this returns 400
Scanner in = new Scanner(inputStream);
String responseStr = "";
while (in.hasNextLine()) {
String str = in.nextLine();
responseStr += str;
}
System.out.println(builder);
System.out.println("responseStr: " + responseStr);
} catch (Exception e) {
}
}
Also I need to create in my webapp a connection to another server by using basic auth (without certificate):
private InputStream connectHTTPS(String loginData, String url, String params) {
TrustManager[] trustAllCerts =
new TrustManager[]{
new X509TrustManager(){
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
}};
HostnameVerifier verifier = new HostnameVerifier() {
public boolean verify(String string, SSLSession sSLSession) {
return true;
}
public boolean verify(String string, String string2) {
return true;
}
};
SSLContext sc = null;
try{
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(verifier);
}catch(Exception e){
e.printStackTrace();
}
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(verifier);
URL serverURL = null;
try{
serverURL = new URL(null,url,new sun.net.www.protocol.https.Handler());
}catch (Exception e){
e.printStackTrace();
}
javax.net.ssl.HttpsURLConnection urlConn = null;
try{
urlConn = (javax.net.ssl.HttpsURLConnection)serverURL.openConnection();
urlConn.setSSLSocketFactory(sc.getSocketFactory());
urlConn.setRequestMethod("POST");
}catch(Exception i){
i.printStackTrace();
}
InputStream res = null;
urlConn.setDoOutput(true);
if(useLogin)
urlConn.setRequestProperty("Authorization", "Basic " + loginData);
urlConn.setUseCaches(false);
urlConn.setAllowUserInteraction(true);
urlConn.setRequestProperty("Pragma", "no-cache");
urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
urlConn.setRequestProperty("Content-length", Integer.toString(params.length()));
try{
PrintStream out = new PrintStream(urlConn.getOutputStream());
out.print(params);
out.flush();
out.close();
res = urlConn.getInputStream();
}catch(Exception o){
o.printStackTrace();
}
return res;
}
If connectHTTPS() is invoked before connectCert() then I get
<html><head><title>400 No required SSL certificate was sent</title></head><body
bgcolor="white"><center><h1>400 Bad Request</h1></center><center>No required SSL certificate was sent</center><hr><center>nginx</center></body></html>
How can I solve the cert issue with the both connections in one webapp?
The issue was resolved by modifying the connectHTTPS() and removing all ssl factory/context configuration. The connectCert() was not changed. The updated method looks like below
private InputStream connectHTTPS(boolean useLogin, boolean showServerError, String loginData, String url, String params) {
InputStream res = null;
HttpURLConnection connect =null;
try{
URL theURL = new URL(url);
connect = (HttpURLConnection)theURL.openConnection();
connect.setRequestMethod("POST");
connect.setUseCaches(false);
connect.setDoOutput(true);
if(useLogin)
connect.setRequestProperty("Authorization", "Basic " + loginData);
connect.setRequestProperty("Pragma", "no-cache");
connect.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
connect.setRequestProperty("Content-length", Integer.toString(params.length()));
PrintStream out = new PrintStream(connect.getOutputStream());
out.print(params);
out.flush();
out.close();
res = connect.getInputStream();
}catch(IOException iox){
if (showServerError && connect != null){
res = connect.getErrorStream();
} else {
res = new ByteArrayInputStream((iox.getMessage()).getBytes());
}
}
return res;
}
Thank you pedrofb for the suggestions.

SOAPHandler for WSSecurity with Digital Signature

I am trying to create a Soap client in java, where I have to Sign the Soap message using my private key.
I am getting response using SoapUI, with WS-Security configured.
I have imported the WSDL and generated classes using wsimport.
I created a SOAPHandler to sign the message like below. I am not sure If this is the correct way to sign the message.
#Override
private void handleMessage(SOAPMessageContext context) throws SOAPException, WSSecurityException {
try {
SOAPMessage soapMessage = context.getMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
soapMessage.getSOAPHeader();
WSSecHeader wsSecHeader = new WSSecHeader();
wsSecHeader.setMustUnderstand(true);
wsSecHeader.insertSecurityHeader(soapPart);
WSSecTimestamp wsSecTimeStamp = new WSSecTimestamp();
wsSecTimeStamp.prepare(soapPart);
wsSecTimeStamp.prependToHeader(wsSecHeader);
WSSConfig wssConfig = new WSSConfig();
WSSecSignature sign = new WSSecSignature(wssConfig);
sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
Properties cxfProps = new Properties();
cxfProps.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jks");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", "example.com");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "password");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", "keystore.jks");
Crypto crypto1 = CryptoFactory.getInstance(cxfProps);
sign.prepare(soapPart, crypto1, wsSecHeader);
String bstId = sign.getBSTTokenId();
sign.appendBSTElementToHeader(wsSecHeader);
sign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
sign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
Vector<WSEncryptionPart> signParts = new Vector<WSEncryptionPart>();
signParts.add(new WSEncryptionPart(wsSecTimeStamp.getId()));
signParts.add(new WSEncryptionPart(WSConstants.ELEM_BODY,
WSConstants.URI_SOAP12_ENV, ""));
signParts.add(new WSEncryptionPart(bstId));
sign.addReferencesToSign(signParts, wsSecHeader);
List<Reference> referenceList = sign.addReferencesToSign(signParts,
wsSecHeader);
sign.computeSignature(referenceList, false, null);
} catch (Exception ex) {
Logger.getLogger(SecurityHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
I am getting a NullPointerException.
java.lang.NullPointerException
at sun.security.provider.JavaKeyStore$JKS.convertAlias(JavaKeyStore.java:57)
at sun.security.provider.JavaKeyStore.engineGetCertificateChain(JavaKeyStore.java:153)
at sun.security.provider.JavaKeyStore$JKS.engineGetCertificateChain(JavaKeyStore.java:55)
at java.security.KeyStore.getCertificateChain(KeyStore.java:1036)
at org.apache.ws.security.components.crypto.Merlin.getX509Certificates(Merlin.java:1277)
at org.apache.ws.security.components.crypto.Merlin.getX509Certificates(Merlin.java:600)
at org.apache.ws.security.message.WSSecSignature.getSigningCerts(WSSecSignature.java:793)
at org.apache.ws.security.message.WSSecSignature.prepare(WSSecSignature.java:169)
at app.SecurityHandler.handleOutboundMessage(SecurityHandler.java:187)
In order to select target private key from your keystore you have to add
sign.setUserInfo("key-alias", "key-password");
in your code.

How to do an HTTPS POST from Android?

I want to do a HTTPS post method to send some data from my android app to my website.
I used HttpURLConnection first and it's working fine with my HTTP URL. My production website is on HTTPS and I want to send the same POST using HttpsURLConnection. Can someone help me use the class properly?
I found some source at this link:
KeyStore keyStore = ...;
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(keyStore);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL url = new URL("https://www.example.com/");
HttpsURLConnection urlConnection = (HttpsURLConnection)
url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
What should be the value of KeyStore keyStore = ...;?
I tried sending the data using the same HttpURLConnection, but I am seeing some POST data is missed or in error.
I've tried the method from this question. I am pasting my code below
String urlParameters="dateTime=" + URLEncoder.encode(dateTime,"UTF-8")+
"&mobileNum="+URLEncoder.encode(mobileNum,"UTF-8");
URL url = new URL(myurl);
HttpsURLConnection conn;
conn=(HttpsURLConnection)url.openConnection();
// Create the SSL connection
SSLContext sc;
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new java.security.SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setConnectTimeout(HTTP_CONNECT_TIME_OUT);
conn.setReadTimeout(HTTP_READ_TIME_OUT);
//set the output to true, indicating you are outputting(uploading) POST data
conn.setDoOutput(true);
//once you set the output to true, you don't really need to set the request method to post, but I'm doing it anyway
conn.setRequestMethod("POST");
conn.setFixedLengthStreamingMode(urlParameters.getBytes().length);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(urlParameters);
out.close();
InputStream is = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response += inputLine;
}
The error I am getting is below:
05-12 19:36:10.758: W/System.err(1123): java.io.FileNotFoundException: https://www.myurl.com/fms/test
05-12 19:36:10.758: W/System.err(1123): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
05-12 19:36:10.758: W/System.err(1123): at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:270)
05-12 19:36:10.758: W/System.err(1123): at .httpRequest(SMSToDBService.java:490)
05-12 19:36:10.758: W/System.err(1123): at com..access$0(SMSToDBService.java:424)
05-12 19:36:10.758: W/System.err(1123): at com.$ChildThread$1.handleMessage(SMSToDBService.java:182)
05-12 19:36:10.758: W/System.err(1123): at android.os.Handler.dispatchMessage(Handler.java:99)
05-12 19:36:10.758: W/System.err(1123): at android.os.Looper.loop(Looper.java:156)
05-12 19:36:10.758: W/System.err(1123): at com.$ChildThread.run(SMSToDBService.java:303)
You can use the default CAs that are defined in the android device, which is just fine for any public web.
If you have a self-signed certificate, you can either accept all certificates (risky, open to man-in-the-middle attacks) or create your own TrustManagerFactory, which is a bit out of this scope.
Here's some code to use the default CAs for a https POST call:
private InputStream getInputStream(String urlStr, String user, String password) throws IOException
{
URL url = new URL(urlStr);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
// Create the SSL connection
SSLContext sc;
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new java.security.SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
// Use this if you need SSL authentication
String userpass = user + ":" + password;
String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT);
conn.setRequestProperty("Authorization", basicAuth);
// set Timeout and method
conn.setReadTimeout(7000);
conn.setConnectTimeout(7000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
// Add any data you wish to post here
conn.connect();
return conn.getInputStream();
}
To read the response:
String result = new String();
InputStream is = getInputStream(urlStr, user, password);
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result += inputLine;
}
You can take a look at this question I asked a few days ago:
Change HTTP post request to HTTPS post request:
I have supplied there a solution that worked for me, that basically accepts any self-signed certificate. As been said here this solution is not recommended as it's not secure and open to a man-in-the-middle attacks.
Here is the code:
EasySSLSocketFactory:
public class EasySSLSocketFactory implements SocketFactory, LayeredSocketFactory {
private SSLContext sslcontext = null;
private static SSLContext createEasySSLContext() throws IOException {
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null);
return context;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
private SSLContext getSSLContext() throws IOException {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
/**
* #see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, java.lang.String, int,
* java.net.InetAddress, int, org.apache.http.params.HttpParams)
*/
public Socket connectSocket(Socket sock, String host, int port, InetAddress localAddress, int localPort,
HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
// we need to bind explicitly
if (localPort < 0) {
localPort = 0; // indicates "any"
}
InetSocketAddress isa = new InetSocketAddress(localAddress, localPort);
sslsock.bind(isa);
}
sslsock.connect(remoteAddress, connTimeout);
sslsock.setSoTimeout(soTimeout);
return sslsock;
}
/**
* #see org.apache.http.conn.scheme.SocketFactory#createSocket()
*/
public Socket createSocket() throws IOException {
return getSSLContext().getSocketFactory().createSocket();
}
/**
* #see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
*/
public boolean isSecure(Socket socket) throws IllegalArgumentException {
return true;
}
/**
* #see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, java.lang.String, int,
* boolean)
*/
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
// -------------------------------------------------------------------
// javadoc in org.apache.http.conn.scheme.SocketFactory says :
// Both Object.equals() and Object.hashCode() must be overridden
// for the correct operation of some connection managers
// -------------------------------------------------------------------
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
}
public int hashCode() {
return EasySSLSocketFactory.class.hashCode();
}
}
EasyX509TrustManager:
public class EasyX509TrustManager implements X509TrustManager {
private X509TrustManager standardTrustManager = null;
/**
* Constructor for EasyX509TrustManager.
*/
public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
super();
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init(keystore);
TrustManager[] trustmanagers = factory.getTrustManagers();
if (trustmanagers.length == 0) {
throw new NoSuchAlgorithmException("no trust manager found");
}
this.standardTrustManager = (X509TrustManager) trustmanagers[0];
}
/**
* #see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
*/
public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
standardTrustManager.checkClientTrusted(certificates, authType);
}
/**
* #see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
*/
public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
if ((certificates != null) && (certificates.length == 1)) {
certificates[0].checkValidity();
} else {
standardTrustManager.checkServerTrusted(certificates, authType);
}
}
/**
* #see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {
return this.standardTrustManager.getAcceptedIssuers();
}
}
And I added this method: getNewHttpClient()
public static HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
Finally for every place in my code that I had:
DefaultHttpClient client = new DefaultHttpClient();
I replace it with:
HttpClient client = getNewHttpClient();
Here's an Android HttpsUrlConnection POST solution complete with certificate pinning, timeouts server side code and configurations.
The variable params should be in the form username=demo&password=abc123&.
#Override
public String sendHttpRequest(String params) {
String result = "";
try {
URL url = new URL(AUTHENTICATION_SERVER_ADDRESS);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(KeyPinStore.getInstance().getContext().getSocketFactory()); // Tell the URLConnection to use a SocketFactory from our SSLContext
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.println(params);
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()), 8192);
String inputLine;
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
in.close();
//} catch (IOException e) {
} catch (IOException | KeyStoreException | CertificateException | KeyManagementException | NoSuchAlgorithmException e) {
result = e.toString();
e.printStackTrace();
}
return result;
}

https Session and posting problem

I have an application that needs to be able to post to https with an authentication request and then a register request. Currently i am able to post my authentication request to https and it works fine. When i try to post my registration request to https i keep getting the server response saying that i need to authenticate. I am authenticating before i attempt to register.
The admin of the server said that i might not be preserving the session. I am new to doing stuff with android and java. And i am new to this https stuff. I was wondering if someone could help me out here, i do not know if that is the problem for sure or even how to preserve an https session in android.
Below is my code and any suggestions are greatly appreciated!!!! Thanks in advance!!
//my helper class
public class SmartDBHelper {
private static Context tThis;
private static SmartDBHelper sDBHObject;
private static String macAddress;
private static String ipAddress;
private static HttpsURLConnection https;
/* constructor, private prevents any other class from instantiating */
private SmartDBHelper() {
}
public static synchronized SmartDBHelper getSDBHObject() {
if(sDBHObject == null) {
sDBHObject = new SmartDBHelper();
}
return sDBHObject;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
public static synchronized void setSmartContext(SmartApp smartApp) {
tThis = (Context) smartApp;
}
private static synchronized void setMACIPAddress() {
WifiManager wifiMan = (WifiManager) tThis.getSystemService (tThis.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
macAddress = wifiInf.getMacAddress().replace(':', '-');
ipAddress = wifiMan.getDhcpInfo().toString();
int startIndex = ipAddress.indexOf(' ');
int endIndex = ipAddress.indexOf(' ', startIndex + 1);
ipAddress = ipAddress.substring(startIndex + 1, endIndex);
}
/* this function is to authenticate with the database
* it returns the id_subject, if it is greater than 0
* authentication was successful.
*/
public static synchronized int authenticate() throws MalformedURLException, ProtocolException, IOException {
Map<String, String> tempMap = new LinkedHashMap<String, String>();
tempMap.put((String) tThis.getResources().getText(R.string.postAction), (String) tThis.getResources().getText(R.string.postAuthenticate));
tempMap.put((String) tThis.getResources().getText(R.string.authUName), "username");
tempMap.put((String) tThis.getResources().getText(R.string.authPWord), "password");
String tempUrl = "https://ipaddress/health_monitoring/admin.php";
return Integer.parseInt(post(tempUrl, tempMap));
}
/* this function is to register the server to the database
* not sure of return value
*/
public static synchronized int registerServer(String nameOfServer, String description) throws MalformedURLException, ProtocolException, IOException {
setMACIPAddress();
Map<String, String> tempMap = new LinkedHashMap<String, String>();
tempMap.put((String) tThis.getResources().getText(R.string.postAction), (String) tThis.getResources().getText(R.string.postAddServer));
tempMap.put((String) tThis.getResources().getText(R.string.addServerName), "Phone");
tempMap.put((String) tThis.getResources().getText(R.string.addServerDescription), "Android");
tempMap.put((String) tThis.getResources().getText(R.string.addServerURL), "");
tempMap.put((String) tThis.getResources().getText(R.string.addServerIPAddress), ipAddress);
tempMap.put((String) tThis.getResources().getText(R.string.addServerMAC), macAddress);
String tempUrl = "https://ipaddress/health_monitoring/admin.php";
return Integer.parseInt(post(tempUrl, tempMap));
}
// always verify the host - dont check for certificate
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
/**
* Trust every server - dont check for any certificate
*/
private static void trustAllHosts() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
private static String post(String urlString, Map formParameters)
throws MalformedURLException, ProtocolException, IOException {
DataOutputStream ostream = null;
trustAllHosts();
URL tempUrl;
StringBuffer buf = new StringBuffer();
if(formParameters != null) {
Set parameters = formParameters.keySet();
Iterator it = parameters.iterator();
for(int i = 0, paramCount = 0; it.hasNext(); i++) {
String parameterName = (String) it.next();
String parameterValue = (String) formParameters.get(parameterName);
if(parameterValue != null) {
parameterValue = URLEncoder.encode(parameterValue);
if(paramCount > 0) {
buf.append("&");
}
buf.append(parameterName);
buf.append("=");
buf.append(parameterValue);
++paramCount;
}
}
}
urlString = urlString + "?" + buf;
Log.v("smartdbhelper url string", urlString);
tempUrl = new URL(urlString);
https = (HttpsURLConnection) tempUrl.openConnection();
https.setHostnameVerifier(DO_NOT_VERIFY);
Log.v("smartdbhelper adding post parameters", https.toString());
https.setRequestMethod("POST");
https.setDoInput(true);
https.setDoOutput(true);
ostream = new DataOutputStream(https.getOutputStream());
ostream.writeBytes(buf.toString());
if( ostream != null ) {
ostream.flush();
ostream.close();
}
Object contents = https.getContent();
InputStream is = (InputStream) contents;
StringBuffer buf2 = new StringBuffer();
int c;
while((c = is.read()) != -1) {
buf2.append((char)c);
Log.v("smartdbhelper bugger", buf2.toString());
}
//https.disconnect();
return buf2.toString();
}
}
It sounds like you probably need to handle cookie headers to preserve the session. If that's the case this isn't specific to HTTPS. You'll need to find the Set-Cookie response header when you make the first request. Then every request after that you'll pass those through a Cookie request header. Here's a basic example that you can adapt for your case:
// your first request that does the authentication
URL authUrl = new URL("https://example.com/authentication");
HttpsURLConnection authCon = (HttpsURLConnection) authUrl.openConnection();
authCon.connect();
// temporary to build request cookie header
StringBuilder sb = new StringBuilder();
// find the cookies in the response header from the first request
List<String> cookies = authCon.getHeaderFields().get("Set-Cookie");
if (cookies != null) {
for (String cookie : cookies) {
if (sb.length() > 0) {
sb.append("; ");
}
// only want the first part of the cookie header that has the value
String value = cookie.split(";")[0];
sb.append(value);
}
}
// build request cookie header to send on all subsequent requests
String cookieHeader = sb.toString();
// with the cookie header your session should be preserved
URL regUrl = new URL("https://example.com/register");
HttpsURLConnection regCon = (HttpsURLConnection) regUrl.openConnection();
regCon.setRequestProperty("Cookie", cookieHeader);
regCon.connect();

Categories

Resources