I manage to log in and get cookies with respect to the session. But when I try to make a new request the login-information seems to be lost (the HTML-data is the same for both the requests. The second request should provide my username plus some other data).
I set the cookie like this before I send a new request (the DefaultHttpClient instance is the same):
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if(cookies != null)
{
for(Cookie cookie : cookies)
{
String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();
httppost.addHeader("Cookie",cookie.getName() + "=" + cookie.getValue() + ";");
System.out.println(cookieString);
}
}
try
{
//System.out.println(httpclient.getCookieStore().getCookies());
response = (BasicHttpResponse) httpclient.execute(httppost,localContext);
}
I have checked the cookie information, and it seems that it returns two different "cookie-instances" (two session ID`s) which I set in the for-loop above. But still it doesn't seem to work.
What can be the problem?
Thanks for any help!
// Create a static instance of cookie store globally
cookieStore = new BasicCookieStore();
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
//execute your connection with context
HttpResponse response = http.execute(post,localContext);
And then whenever you connect use that static cookie instance to connect
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, StaticInstance(cookieStore));
//and as usual
response = http.execute(post,localContext);
Related
I'm trying to execute import via java using ModifiableSolrParams:
Can you please point me on the right direction or reference on how to add security credentials (username / password) to trigger the import.
Current code
SolrServer server = new HttpSolrServer(baseurl);
ModifiableSolrParams params = new ModifiableSolrParams();
params.set("command", "full-import");
params.set("clean", "true");
params.set("commit", "true");
QueryRequest request = new QueryRequest(params);
request.setPath("/dataimport");
server.request(request);
You need to add HttpRequestInterceptor to you HttpServer. This interceptor will be able to add authorization header to every your request.
For cloud Solr the util class that allow to do this is HttpClientUtil. You can start from this class, or check where in HttpSolrServer is actually HttpClient present.
I veered away from Solrj and went with this approach instead.
HttpClient Client = new DefaultHttpClient();
String userpass = usr + ":" + pwd;
HttpPost httpGet = new HttpPost(dataimport_cmd);
String encoding =
DatatypeConverter.printBase64Binary(userpass.getBytes("UTF-8"));
httpGet.setHeader("Authorization", "Basic " + encoding);
Client.execute(httpGet);
I need to obtain the input stream to a HTTPS URL eg. https://baseurl.com/mypdfgenerated.php?param=somevalue. In order to access this URL I need to get through the login page (eg. https://baseurl.com/login.php) by supplying BODY parameters:
user_name, web_pwd and submit_login
I'm assuming the only way to successfully access the first URL is by a POST to the /login.php followed by storing the cookies and then reusing the cookie-session-ID in the next GET request; if this is the correct approach then could someone please share a solution with the correct/recent libraries?
Not sure which is the best way but what helped me achieve this is the CloseableHttpClient class which along with BasicCookieStore retains cookies for subsequent requests once logged in, implemented below:
BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
HttpUriRequest login = RequestBuilder.post()
.setUri(new URI(url_login))
.addParameter("login", "loginuname")
.addParameter("password", "pwd")
.addParameter("submit", "sub_mit");
CloseableHttpResponse response = httpclient.execute(login);
List<Cookie> cookies = cookieStore.getCookies();
response.close();
HttpGet httpget2 = new HttpGet(url_to_get_after_login);
CloseableHttpResponse response2 = httpclient.execute(httpget2);
response2.close();
Sample code snippet from Java Samples
try {
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
URL url = new URL("https://www.yourwebsite.com/"); // Some URL
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setFollowRedirects(true);
String query = "UserID=" + URLEncoder.encode("username");
query += "&";
query += "password=" + URLEncoder.encode("password");
query += "&";
// open up the output stream of the connection
DataOutputStream output = new DataOutputStream( connection.getOutputStream() );
// write out the data
output.writeBytes( query );
}catch(Exception err){
err.printStackTrace();
}
Have a look at Usage of cookies
You should use a library which handles cookies for you, such as Apache HTTPClient.
What I want:
Send a GET request with a preemtive bassic authentication.
The request looks about like this:
<startURL>/app/process?job=doSomething¶m=value1,value2
whereas startURL is always a https link depends on the enviroment.
Looks something like this:
https://testABC.com
https://prodABC.com
startURL is also placed in a properties file as is for the diffrent enviroments.
What I looked into:
http://www.baeldung.com/httpclient-4-basic-authentication
http://www.java-tips.org/other-api-tips/httpclient/how-to-use-basic-authentication.html
http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html
It all contains a
HttpHost targetHost = new HttpHost("hostname", portnumber, "scheme");
Which is what I am having trouble with. This method is also the only one that lets you specify the scheme as "https".
One issue is, hat I don't know the portnumber. I think (?) I probably could just specify -1 for the default port, to make it work, but even aside that I also don't have the hostname, only the above mentioned startURL. I don't really want to parse this extra each time, while I also don't really want to add another property, just for the hostname.
I digged around and found this snippet, which looks like just what I want:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://foo.com/bar");
httpGet.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials("user", "password"),
"UTF-8", false));
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity responseEntity = httpResponse.getEntity();
from HTTP requests with basic authentication
It gives the complete request URL and simply adds the basic header and does not need any port specified. Only that this is now deprecated since Version 4.2:
Deprecated. (4.2) Use ContextAwareAuthScheme.authenticate( Credentials, HttpRequest, org.apache.http.protocol.HttpContext)
I couldn't find a single example for this method to return the basic auth header. It also wants a context as a parameter, which above snipped doesn't have. I really have no real clue how this is supposed to be used.
So, what i want to know concretely:
I just want to set up a request with the complete link, that contains all that there is, like:
https://testABC.com/app/process?job=doSomething¶m=value1,value2
and just give this as a parameter for a request that does preemptive basic authentication.
Is there any way to do this without digging up the deprecated methods and how does it look like?
I ran into the same problem as yours.
What worked for me is the following:
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "12345");
HttpGet get = new HttpGet("https://foo.bar.com/rest");
HttpHost targetHost = new HttpHost("foo.bar.com", 443, "https");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
creds);
credsProvider.setCredentials(AuthScope.ANY,creds);
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpResponse response = client.execute(targetHost, get, context);
And I found this solution on: HttpClientBuilder basic auth
In the end I wound up writing the header manually on my own and sending things with that:
String header = "Basic ";
String headerValue = "username" + ":" + "password";
String encodedHeaderValue = Base64.encodeBase64String(headerValue.getBytes());
String headerBasic = header + encodedHeaderValue;
Header authHeader = new BasicHeader("Authorization", headerBasic);
ArrayList<Header> headers = new ArrayList<Header>();
headers.add(authHeader);
ArrayList<Header> headers = getHttpHeaders();
HttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();
HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();
I have a problem with the HttpClient in Android: By using the following code, I want to use the cookies which are already set before by logging in through a webview. So the login data should be there and is indeed there, I tested it. But when I use the cookies in an httppost or httpget it doesn't use the login data. but these cookies actually should be enough to receive that page for which a login is necessary, shouldn't they? I'm not really sure if I need to send the cookies in a special way to the server or so or if it is enough to load it into the httpcontext. Here is the code:
DefaultHttpClient httpclient = new DefaultHttpClient();
CookieStore lCS = new BasicCookieStore();
if (CookieManager.getInstance().getCookie(pUrl) != null) {
String cookieString = CookieManager.getInstance().getCookie(pUrl);
String[] urlCookieArray = cookieString.split(";");
for (int i = 0; i < urlCookieArray.length; i++) {
System.out.println(urlCookieArray[i]);
String[] singleCookie = urlCookieArray[i].split("=");
Cookie urlCookie = new BasicClientCookie(singleCookie[0], singleCookie[1]);
lCS.addCookie(urlCookie);
}
}
HttpContext localContext = new BasicHttpContext();
httpclient.setCookieStore(lCS);
localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);
HttpPost httppost = new HttpPost(pUrl);
// get the url connection
try {
StringBuilder sb = new StringBuilder();
HttpResponse response = httpclient.execute(httppost, localContext);
InputStream is = response.getEntity().getContent();
InputStreamReader isr = new InputStreamReader(is);
And if I run the code I only receive the login page of that site, so it didn't accept the cookie.
Thanks for help in advance
Greets, timo
I had the same problem and I used similar approach as in the question with no luck.
The thing that made it work for me was to add the domain for each copied cookie.
(BasicClientCookie cookie.setDomain(String))
My util function:
public static BasicCookieStore getCookieStore(String cookies, String domain) {
String[] cookieValues = cookies.split(";");
BasicCookieStore cs = new BasicCookieStore();
BasicClientCookie cookie;
for (int i = 0; i < cookieValues.length; i++) {
String[] split = cookieValues[i].split("=");
if (split.length == 2)
cookie = new BasicClientCookie(split[0], split[1]);
else
cookie = new BasicClientCookie(split[0], null);
cookie.setDomain(domain);
cs.addCookie(cookie);
}
return cs;
}
String cookies = CookieManager.getInstance().getCookie(url);
BasicCookieStore lCS = getCookieStore(cookies, MyApp.sDomain);
HttpContext localContext = new BasicHttpContext();
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setCookieStore(lCS);
localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);
...
if you still have this problem, be careful with the given cookies, some might be malformed, check these two sites out:
http://www.codeproject.com/Articles/3106/On-The-Care-and-Handling-of-Cookies
this one helped me:
Getting "Set-Cookie" header
It seems you are copying the cookies correctly, and generally you don't need to do anything special for HttpClient to send the cookies. However, some of those may be bound to a session, and when you open a new connection with HttpClient you open a new session. The server will probably ignore cookies that don't match the current session. This might work if the session ID is in a cookie and you are able to get into the same session, but you really need to know exactly what the server does.
I have a an app that should send a GET request to a URL and send some cookies along with it. I've been looking at a few code examples for BasicCookieStore and Cookie classes, but I'm not able to figure out how to use them. Can anyone point me in the right direction?
To use cookies you need something along the lines of:
CookieStore cookieStore = new BasicCookieStore();
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext ctx = new BasicHttpContext();
ctx.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet get = new HttpGet("your URL here");
HttpResponse response = httpclient.execute(get,ctx);
And if you want to keep cookies between requests, you have to reuse cookieStore and ctx for every request.
Also, you may read your cookieStore to see what's inside:
List<Cookie> cookies = cookieStore.getCookies();
if( !cookies.isEmpty() ){
for (Cookie cookie : cookies){
String cookieString = cookie.getName() + " : " + cookie.getValue();
Log.info(TAG, cookieString);
}
}