Why is httpclient is refreshing the jsession id for every request? - cookies

I am trying to hit a url(login screen), get the jsessionid(J2EEJSESSIONID) and add it in the cookie store and in turn in to the context and hit the same url with credentials. I am expecting a login successful screen.
However i am bounced with the login screen again.
And, i printed the response header for both the hits. I am expecting both the response with the same J2EESESSIONID to maintain the session. Instead both the session ids are different. Pls help.
Pls find the code below:
HttpEntity entity = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
try{
// Initialization
HttpPost httpPost = new HttpPost("https://yyyyy.xxx.com/enl");
HttpClientExample httpClientExample = new HttpClientExample();
CookieStore cookieStore = new BasicCookieStore();
HttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpGet = new HttpGet("https://yyyyy.xxx.com/enl");
// Execute Get
HttpResponse httpResponse = httpClient.execute(httpGet, httpContext);
// Print the header for 1st url
org.apache.http.Header[] headers = httpResponse.getAllHeaders();
System.out.println("##### Header length::"+headers.length);
for(int i=0;i<headers.length; i++)
{
System.out.println("Header Name::"+headers[i].getName());
System.out.println("Header Val::"+headers[i].getValue());
}
// update Cookie for the next hit
org.apache.http.Header[] cookieHeaders = httpResponse.getHeaders("Set-Cookie");
String html = EntityUtils.toString(httpResponse.getEntity());
cookieStore = httpClientExample.updateCookieStore(cookieHeaders, cookieStore);
httpClient.setCookieStore(cookieStore);
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
// Setting the redirects since i received 302 error
httpClient.setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return false;
}
});
// Added because i received Circular redirect error
httpClient.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
// Execute Post with credentials
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("http://yyyyy.xxx.com", 443),
new UsernamePasswordCredentials("usr", "pswd"));
httpPost.setHeader("Cookie", "JSESSIONID="+ getSessionId(cookieHeaders));
HttpResponse response = httpClient.execute(httpPost, httpContext);
// Print the response
entity = response.getEntity();
InputStream content1 = (InputStream)entity.getContent();
System.out.println("############### 2nd #####################"+response.getStatusLine().getStatusCode());
BufferedReader in1 =
new BufferedReader (new InputStreamReader (content1));
String line1;
while ((line1 = in1.readLine()) != null) {
System.out.println(line1);
}
// Print the header for 2nd url
org.apache.http.Header[] headers1 = response.getAllHeaders();
System.out.println("##### Header length 2 ::"+headers1.length);
for(int i=0;i<headers1.length; i++)
{
System.out.println("Header Name 2 ::"+headers1[i].getName());
System.out.println("Header Val 2 ::"+headers1[i].getValue());
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
try {
EntityUtils.consume(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
httpClient.getConnectionManager().shutdown();
}
}
private static String getSessionId(org.apache.http.Header[] headers) {
// TODO Auto-generated method stub
for(int i=0;i<headers.length; i++)
{
String str = headers[i].getValue();
String[] strArray = str.split("=");
String[] cookieValueArray = strArray[1].split(";");
System.out.println(strArray[0]+"|"+cookieValueArray[0]);
if(strArray[0].startsWith("J2EEJSESSION"))
{
System.out.println("cookieValueArray[0]:"+cookieValueArray[0]);
return cookieValueArray[0];
}
}
return null;
}
protected CookieStore updateCookieStore(org.apache.http.Header[] headers, CookieStore cookieStore)
{
for(int i=0;i<headers.length; i++)
{
String str = headers[i].getValue();
String[] strArray = str.split("=");
String[] cookieValueArray = strArray[1].split(";");
System.out.println(strArray[0]+"|"+cookieValueArray[0]);
BasicClientCookie cookie = new BasicClientCookie(strArray[0], "A"+cookieValueArray[0]);
/*if(strArray[0].startsWith("J2EEJSESSION"))
{
cookie.setDomain("yyyyy.xxx.com");
}
else
{
cookie.setDomain(".xxx.com");
}*/
cookie.setDomain(".xxx.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
if(strArray[0].startsWith("J2EEJSESSION"))
{
BasicClientCookie cookie1 = new BasicClientCookie("JSESSIONID", "A"+cookieValueArray[0]);
cookie1.setDomain(".xxx.com");
cookie1.setPath("/");
cookieStore.addCookie(cookie1);
}
}
return cookieStore;
}
Another observation:
When i remove the "A" concat from the below snippet, i am not getting the J2EESESSIONID in the 2nd hit:
BasicClientCookie cookie = new BasicClientCookie(strArray[0], "A"+cookieValueArray[0]);

Found the answer on the same day I posted this question.. thought of sharing..
The answer is very simple.. For some reasons the authentication wasn't successful, hence the new jsessionId was created. Replaced "httpClient.getCredentialsProvider().setCredentials()" with "BasicNameValuePair" and it worked :)

Related

Retrieving cookies from httprequest in Xamarin.forms

help me, i couldn't get the cookies from an httprequest, i tried the plugins.settings, i tried the pcl share too, am in this problem for a month
public async Task<bool> PostAsync(AuthUser user)
{
var CookieContainer = new CookieContainer();
var handler = new HttpClientHandler() { CookieContainer =
CookieContainer };
var _client = new HttpClient(handler);
IEnumerable<string> cookieStrings = null;
//var httpClient = new HttpClient();
_client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
var json = JsonConvert.SerializeObject(user);
HttpContent httpContent = new StringContent(json);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
try
{
string url = WebServiceUrl + "j_spring_security_check?j_username=" + user.j_username +"&j_password=" + user.j_password + "&ajax=true";
HttpResponseMessage result = await _client.PostAsync(url, httpContent);
IEnumerable<string> cookies;
if (result.Headers.TryGetValues("set-cookie", out cookies))
{
foreach (var c in cookies)
{
await App.Current.MainPage.DisplayAlert("Cookie", c , "OK");
}
}
if (result.IsSuccessStatusCode)
{
using (var responsecontent = result.Content)
{
string resultString = responsecontent.ReadAsStringAsync().Result;
var response = JsonConvert.DeserializeObject<AuthUser>(resultString);
if (response.error != null)
{
await App.Current.MainPage.DisplayAlert("Error", response.result.error, "OK");
return false;
}
else if (response.result.success.Equals("1"))
{
App.Current.MainPage = new NavigationPage(new TimelineMenuPage(response.result.user_id.ToString(), response.result.token));
return true;
}
}
}
return result.IsSuccessStatusCode;
}
catch (Exception e)
{
await App.Current.MainPage.DisplayAlert("Alert", e.ToString(), "OK");
throw;
}
}
when debugging it skips this part :
if (result.Headers.TryGetValues("set-cookie", out cookies))
{
foreach (var c in cookies)
{
await App.Current.MainPage.DisplayAlert("Cookie", c , "OK");
}
}
**and then i get in CookieContainer count=0 **
Since you are already using a CookieContainer, and you will know the Uri you are getting them from, why don't you just get the Cookies directly from the Container, instead of a set-cookie command, that you will then have to parse.
cookieContainer.GetCookies(new Uri("mydomain.com"));
After your HttpRequest, it will automatically put them into the CookieContainer.

Programe Not Executing in Correct Order in Android Studio

I want to check whether the email id entered by user is unique or not so for that initially I have my variable Boolean valid = false;. On clicking a button i am taking the email id entered and checking it for valid email id expression using regular expression and then i am using an asyntask to check its uniqueness. Code in my onclicklistner is
if (emailid.matches(regexp) && emailid.length() > 0) {
new Validate().execute();
Toast.makeText(getApplicationContext(), valid.toString(), Toast.LENGTH_LONG).show();
if (valid) {
data.putString("eid", eid);
data.putString("firstname", firstname);
data.putString("lastname", lastname);
data.putString("emailid", emailid);
Intent i = new Intent(getApplicationContext(), GamesFragment.class);
startActivity(i);
} else {
Toast.makeText(getApplicationContext(), "Email Address Already Exist", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(), "Check Your Email Address", Toast.LENGTH_LONG).show();
}
Here what problem i am facing is, for first time when i am entering an email which is unique and clicks the button, the Validate() asynctask checks and sets the valid variable to true, but it doesn't goes to next activity GamesFragment because i have declared valid = false initially. Now when i again click the button, then it goes to next activity as the valid variable is set to true because of previous click.
Now My Validate() asynctask is
private class Validate extends AsyncTask<Void, Void, Void> {
#Override
protected Boolean doInBackground(Void... params) {
ArrayList<NameValuePair> emailId = new ArrayList<NameValuePair>();
emailId.add(new BasicNameValuePair("email", emailid));
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("url/validate.php");
httppost.setEntity(new UrlEncodedFormEntity(emailId));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
iss = entity.getContent();
} catch(Exception e) {
Log.e("pass 1", "Connection Error");
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader
(new InputStreamReader(iss,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
iss.close();
result = sb.toString();
} catch(Exception e) {
e.printStackTrace();
}
try {
JSONObject json_data = new JSONObject(result);
code=(json_data.getInt("code"));
if(code == 1)
valid = true;
else
valid = false;
Log.e("pass 3", "valid "+valid);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
Please help i am not getting why this is happening.
Create function to check validation.
private boolean function validate(String emailid){
if (emailid.matches(regexp) && emailid.length() > 0) {
return true;
}
return false;
}
use that function to decide event
if(validate(emailid)){ // if function return true then email is valid and good to go.
new Validate().execute();
}
For second condition you have to check it in your async task onPostExecute() that is Validate();
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
if(code == 1){
// check if response is valid than
Intent i = new Intent(getApplicationContext(), GamesFragment.class);
startActivity(i);
}
}

I am getting a 401 error when I am sending a soap request to a nav web service

I am trying to send an XML soap request to a dynamics nav web service. This is the XML from the WSDL. I have created a web access key and its the one in the key parameter of the XML.
<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
<s11:Body>
<ns1:Create xmlns:ns1='urn:microsoft-dynamics-schemas/page/customerws'>
<ns1:CustomerWS>
<ns1:Key>+gn8Nu4i7iW7D/g9vCaI8HZE5IEi1NBkTBqDp5QfXe4=</ns1:Key>
<ns1:Shipping_Advice></ns1:Shipping_Advice>
<ns1:Shipment_Method_Code></ns1:Shipment_Method_Code>
<ns1:Shipping_Agent_Code></ns1:Shipping_Agent_Code>
<ns1:Shipping_Agent_Service_Code></ns1:Shipping_Agent_Service_Code>
<ns1:Shipping_Time></ns1:Shipping_Time>
<ns1:Base_Calendar_Code></ns1:Base_Calendar_Code>
<ns1:Customized_Calendar></ns1:Customized_Calendar>
<ns1:Currency_Code></ns1:Currency_Code>
<ns1:Language_Code></ns1:Language_Code>
<ns1:VAT_Registration_No></ns1:VAT_Registration_No>
</ns1:CustomerWS>
</ns1:Create>
</s11:Body>
</s11:Envelope>
And this is the code that am using to send this request:
Console.WriteLine("We have started");
string pageName = "http://hrp-dmu.uganda.hrpsolutions.co.ug:9047/DynamicsNAV80/WS/Uganda%20Management%20Institute/Page/CustomerWS";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(pageName);
req.Method = "POST";
req.ContentType = "text/xml;charset=UTF-8";
req.ProtocolVersion = new Version(1, 1);
req.Headers.Add("SOAPAction", #"urn:microsoftdynamicsschemas/page/customerws:Create");
Console.WriteLine("After preparing request object");
string xmlRequest = GetTextFromXMLFile("E:\\tst3.xml");
Console.WriteLine("xml request : "+xmlRequest);
byte[] reqBytes = new UTF8Encoding().GetBytes(xmlRequest);
req.ContentLength = reqBytes.Length;
try
{
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(reqBytes, 0, reqBytes.Length);
}
}
catch (Exception ex)
{
Console.WriteLine("GetRequestStreamException : " + ex.Message);
}
HttpWebResponse resp = null;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (Exception exc)
{
Console.WriteLine("GetResponseException : " + exc.Message);
}
string xmlResponse = null;
if (resp == null)
{
Console.WriteLine("Null response");
}
else
{
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
xmlResponse = sr.ReadToEnd();
}
Console.WriteLine("The response");
Console.WriteLine(xmlResponse);
}
Console.ReadKey();
when using NavUserPassword Authentication you'll need a certificate.
See here on MSDN
Cheers!

Cannot genetrate java client for file upload webservice

I have a simple file upload web service as a small part of my project.
This is what I have done so far on the server side :
#POST
#Path("/file")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(List<Attachment> attachments,#Context HttpServletRequest request) {
System.out.println("Got an attachment!");
for(Attachment attr : attachments) {
DataHandler handler = attr.getDataHandler();
try {
InputStream stream = handler.getInputStream();
MultivaluedMap map = attr.getHeaders();
OutputStream out = new FileOutputStream(new File("/home/yashdosi/s/" + getFileName(map))); //getFileName is a seperate private function..
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
stream.close();
out.flush();
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
return Response.ok("file uploaded").build();
}
It works perfectly well when requests come from html forms...when I try to send a request from a java client it simply doesnt work..!!
Any ideas about on creating a java client for this code..
Here is the code I tried with...maybe there is a simple error in this code but..I dont see it...also as I said this code simple wont work...no errors or anything else....when I tried printing something on the server console to see if the service is invoked...it did NOT print anything..so I think I am unable to contact the service for some reason...
public static void uploadPhoto()
{
String url = "http://localhost:8080/fileupload-ws/services/postdata";
String output = null;
PostMethod mPost = new PostMethod(url);
HttpClient client = new HttpClient();
try
{
File imageFile = new File("/home/yashdosi/1.jpg");
BufferedImage image = ImageIO.read(imageFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
byte[] encodedImage = Base64.encodeBase64(baos.toByteArray());
String data = " " + " " + "" + "image/jpeg" + " " + "" + new String(encodedImage) + " " + "";
mPost.setRequestBody(data);
mPost.setRequestHeader("Content-Type", "text/xml");
client.executeMethod( mPost );
output = mPost.getResponseBodyAsString( );
mPost.releaseConnection( );
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(output);
}
Finally got a client working!!
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost("http://localhost:8080/fileupload-ws/services/postdata");
FileBody img = new FileBody(new File("/home/yashdosi/1.jpg"));
FileBody html = new FileBody(new File("/home/yashdosi/hotmail.html"));
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("image", img);
reqEntity.addPart("html", html);
httppost.setEntity(reqEntity);
httppost.setHeader("Content-Type", "multipart/form-data");
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
}
catch(Exception e)
{
e.printStackTrace();
}
finally {
try { httpclient.getConnectionManager().shutdown(); } catch (Exception ignore) {}
}

clear cookie container in WebRequest

I'm using the WebRequest object to post data to a login page, then post data to a seperate page on the same site. I am instantiating a CookieContainer and assigning it to the WebRequest object so that the cookies are handled. The problem is that I do not want to retain the cookie after I post data to the other page. How can I delete that cookie?
private CookieContainer cookie_m;
protected CookieContainer CookieContainer
{
get
{
if (cookie_m == null)
{
cookie_m = new CookieContainer();
}
return cookie_m;
}
set
{
cookie_m = value;
}
}
protected virtual void SetData(WebRequest request, string sData)
{
if (!String.IsNullOrEmpty(sData))
{
byte[] binPostData = System.Text.Encoding.ASCII.GetBytes(sData);
request.ContentLength = binPostData.Length;
System.IO.Stream sRequest = request.GetRequestStream();
try
{
sRequest.Write(binPostData, 0, binPostData.Length);
}
finally
{
sRequest.Close();
}
}
}
private HttpWebRequest GetNewRequest(string sUrl)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sUrl);
request.CookieContainer = this.CookieContainer;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
return request;
}
public override void Submit()
{
//Login
HttpWebRequest request = GetNewRequest("http://mytest/login.asp");
base.SetData(request, "action=validate_login&login=test&password=test");
WebResponse response = request.GetResponse();
System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream());
string sResponse = sr.ReadToEnd();
//Entry screen
request = GetNewRequest("http://mytest/CustCreate.asp");
base.SetData(request, "Site=xyz&Cust=test");
response = request.GetResponse();
sr = new System.IO.StreamReader(response.GetResponseStream());
sResponse = sr.ReadToEnd();
//Sutmit
request = request = GetNewRequest("http://mytest/CustCreate.asp");
base.SetData(request, "Site=xyz&mydatahere&B1=Submit");
response = request.GetResponse();
sr = new System.IO.StreamReader(response.GetResponseStream());
sResponse = sr.ReadToEnd();
//How to delete cookies that have been saved?
}
To delete a cookie, you need to set the expiration date on it to a date in the past. This tells the browser it's expired and the browser will delete it.
Here's an example from msdn on how to do this in C# (not sure which language you're using).
if (Request.Cookies["UserSettings"] != null)
{
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}