authentication with Java and apache HttpClient 4.5.1 - java

my problem is, that i don't get, how to log in with Java and Apache HttpComponents (HttpClient v4.5.1) into a specific site: Site im trying to log in. I have the username (test_admin) and the password (testing) to log in but i think this is not enough and i need something more. I think this has something to do with the field security_token i see when i make a get request to the uri, but i dont know how to keep that or how to save that and what to do with it afterwards. There is also a hidden input field with the name login-ticket, but i dont know what's that for either. I want to login, because i need to see the courses and add some new ones. After trying with several code implementations im stick with this code:
public static void setGet(CloseableHttpClient httpClient) throws UnsupportedOperationException, IOException
{
HttpGet httpGet = new HttpGet("http://demo.studip.de/dispatch.php/admin/courses");
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
System.out.println("GET Response Status:: "
+ httpResponse.getStatusLine().getStatusCode());
showEntity(httpResponse,httpResponse.getEntity());
}
public static HttpEntity setParam(int count, String[] params, String[] values)
{
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
for (int i = 0; i < count; i++)
{
formparams.add(new BasicNameValuePair(params[i],values[i]));
System.out.println("Paramater------------------> "+params[i]+" Values-------------> "+values[i]);
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
return entity;
}
public static void setPost(HttpClient httpC) throws ClientProtocolException, IOException
{
HttpPost httppost = new HttpPost("http://demo.studip.de/dispatch.php/admin/courses");
//String[] params = {"loginname", "password"};
//String[] values = {"test_admin", "testing"};
//HttpEntity entity = setParam(2, params, values );
HttpResponse response = httpC.execute(httppost);
System.out.println("POST Response Status:: "
+ response.getStatusLine().getStatusCode());
showEntity(response, response.getEntity());
}
public static void showEntity(HttpResponse httpResp, HttpEntity httpClient) throws IOException
{
httpClient = httpResp.getEntity();
if (httpClient != null)
httpClient = new BufferedHttpEntity(httpClient);
System.out.print(EntityUtils.toString(httpClient));
}
public static void main(String[] args) throws InterruptedException, IOException {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("test_admin", "testing"));
CloseableHttpClient hc =
HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build();
setGet(hc);
// HttpClient httpclient = HttpClients.createDefault();
setPost(hc);
setGet(hc);
}
The problem now ist that i get everytime the same answer from the server i only see the login page in the response, where the server asks me to login with username and password.

Which code you get from the server 401,403,301,302 or 200?

Related

Retrofit: Making Web Requests to Internal APIs

I want to make a request to my organisation api's. The request contains Headers, UserName, Password, & Cookie for session management.
Below is the actual code (in HttpClient) which I want to rewrite using Retrofit. I have heard that HttpClient libraries have been deprecated or someting so have opted Retrofit. I expect the response with 200 status code.
public static CookieStore cookingStore = new BasicCookieStore();
public static HttpContext context = new BasicHttpContext();
public String getAuth(String login,String password) {
String resp = null;
try {
String url = DOMAIN+"myxyzapi/myanything";
context.setAttribute(HttpClientContext.COOKIE_STORE, cookingStore);
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
String log = URLEncoder.encode(login, "UTF-8");
String pass = URLEncoder.encode(password, "UTF-8");
String json = "username="+log+"&password="+pass+"&maintain=true&finish=Go";
StringEntity entity = new StringEntity(json);
post.setEntity(entity);
post.addHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse response = client.execute(post,context);
resp = EntityUtils.toString(response.getEntity());
accountPoller();
} catch(Exception a) {
log.info("Exception in authentication api:"+a.getMessage().toString());
}
return resp;
}
Below is my code where I can't figure out how to pass the context with request. HttpResponse response = client.execute(post,**context**); using retrofit.
I don't even know if I have made my retrofit request right.
try {
String log = URLEncoder.encode(login, "UTF-8");
String pass = URLEncoder.encode(password, "UTF-8");
RequestBody formBody = new FormBody.Builder()
.add("username=", xyz)
.add("password=", mypass)
.add("&maintain=", "true")
.add("finish=", "Go")
.build();
String url = www.xyz.com+"myxyzapi/myanything";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).post(formBody).addHeader("Content-Type", "application/x-www-form-urlencoded").build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
final String myresp = response.body().string();
}
}
});
} catch(Exception a) {
a.getMessage();
}
You have to catch exception and use this class.
retrofit2.HttpException
retrofit2
Class HttpException
int
code()
HTTP status code.
String
message()
HTTP status message.
Response
response()
The full HTTP response.

How to get full json response using httprequest

Simply I am trying to hit URL i.e. www.google.com
and I want to capture whole json responce as output ...
I tried multiple codes which help me to find only response code but I want full json response from which I can filter few information.
above thing I am doing for web..
I used ApacheHttpClient jar (version 4.5.1). You'll also need HttpCore library (I used 4.4.3) and maybe some other apache libraries (like codec).
Here are a GET method and a POST method:
public static String getJsonStringHttpGet(String url,Map<String,String> headers) throws IOException {
BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.build();
HttpCoreContext localContext = new HttpCoreContext();
HttpGet get = new HttpGet(url);
/*
* if you need to specify headers
*/
if (headers != null) {
for (String name : headers.keySet()) {
get.addHeader(name, headers.get(name));
}
}
HttpResponse response = httpClient.execute(get, localContext);
byte [] bytes = EntityUtils.toByteArray(response.getEntity());
return new String(bytes);
}
public static String getJsonStringHttpPost(String url,Map<String,String> postParams,Map<String,String> headers) throws IOException {
BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.build();
HttpCoreContext localContext = new HttpCoreContext();
HttpPost post = new HttpPost(url);
/*
* adding some POST params
*/
if (postParams != null && postParams.size() > 0) {
List<BasicNameValuePair> postParameters = new ArrayList<>();
for (String name : postParams.keySet()) {
postParameters.add(new BasicNameValuePair(name, postParams.get(name)));
}
post.setEntity(new UrlEncodedFormEntity(postParameters));
}
/*
* if you need to specify headers
*/
if (headers != null) {
for (String name : headers.keySet()) {
post.addHeader(name, headers.get(name));
}
}
HttpResponse response = httpClient.execute(post, localContext);
byte [] bytes = EntityUtils.toByteArray(response.getEntity());
return new String(bytes);
}
Then you can parse the json string as you like.
Hope this helps

Oauth token requests before provider credentials issuance

Please forgive me if I ask something stupid, I am a novice here. I need to implement OAuth in my Java application to authenticate against launchpad.net API. The documentation specifies an initiation of a token request with three parameters : oauth_consumer_key e.g. (name of my application), oauth_signature_method e.g. "PLAINTEXT" and oauth_signature e.g. The string "&". I realised that most OAuth libraries require that
I have already acquired a Consumer key and Consumer Id/Secret from
the OAuth provider (e.g as issued in Twitter), and most examples are organised in this manner. However, launchpad.net will issue these parameters only after issuance of request token (they use no third party provider). How can I proceed?I am currently stuck after trying some libraries that threw errors. Many thanks for any useful information. The official launchpad library is in python.
My initial code is below:
public class Quicky {
public static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("https://launchpad.net/+request-token");
CloseableHttpResponse response1 = httpclient.execute(httpGet);
try {
System.out.println("Your current GET request status:" + response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
EntityUtils.consume(entity1);
} finally {
response1.close();
}
HttpRequest request;
HttpPost httpPost = new HttpPost("https://launchpad.net/+request-token");
PostMethod poster = new PostMethod();
List <NameValuePair> postParams = new ArrayList <NameValuePair>();
postParams.add(new BasicNameValuePair("oauth_customer_key", "XXXX"));
postParams.add(new BasicNameValuePair("oauth_signature_method", "PLAINTEXT"));
postParams.add(new BasicNameValuePair("oauth_signature", "&"));
httpPost.setEntity(new UrlEncodedFormEntity(postParams, "utf-8"));
// httpPost.setEntity(entity1);
httpclient.execute(httpPost);
HttpParameters requestParams = (HttpParameters) postParams;
CloseableHttpResponse response2 = httpclient.execute(httpPost);
try {
System.out.println("Your current POST request status:" + response2.getStatusLine());
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();
}
}
}
I finally resolved the issue error messages after some research and code re-factoring. The correct code is below, maybe it could be useful to someone out there.
public class LaunchPadTokenRetriever {
public static void main(String[] args) throws ClientProtocolException, IOException{
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("https://launchpad.net/+request-token");
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
List <NameValuePair> urlParams = new ArrayList <NameValuePair>();
urlParams.add(new BasicNameValuePair("oauth_signature", "&"));
urlParams.add(new BasicNameValuePair("oauth_consumer_key", "tester"));
urlParams.add(new BasicNameValuePair("oauth_signature_method", "PLAINTEXT"));
httpPost.setEntity(new UrlEncodedFormEntity(urlParams));
CloseableHttpResponse response = httpclient.execute(httpPost);
System.out.println(response);
try {
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpPost, responseHandler);
System.out.println("Initial credentials ---> "+ responseBody);
System.out.println();
String getresponse = responseBody;
EntityUtils.consume(entity);
} finally {
response.close();
}
}
}

REST PUT with external file JSON to httpClient Java?

I need to translate this for example :
curl -X PUT -u ident:pass -H "Content-Type : application/json" --data-binary #G:\jonJob.json "http://localhost:8080/jobs/"
(this works).
in java with httpClient. I have try a lot of things but nothing work..
Someone could help me please ?
What I've tried :
public class PostFile {
#SuppressWarnings("deprecation")
public static void main(String[] args) throws Exception {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("ident", "pass");
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
HttpPut httppost = new HttpPut("http://localhost:8080/jobs/");
File file = new File("G:/jsonJob.json");
HttpEntity httpEntity = MultipartEntityBuilder.create().addBinaryBody("file", file, ContentType.create("application/json"), file.getName()).build();
httppost.setEntity(httpEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpClient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpClient.getConnectionManager().shutdown();
}
}
Result : "HTTP/1.1 415 Not supported type" (unsupported media type)
for your http req headers -H you have java runnable imple with interceptor:
public void run() {
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(YourConnectionMgr.getInstance())
.addInterceptorLast(new HttpRequestInterceptor() {
public void process(
final HttpRequest request,
final HttpContext context) throws HttpException, IOException {
if (request.getRequestLine().getMethod() == "POST"){
request.addHeader("Content-Type", "application/json") ;
see examples here to figure out 'connectionManager'
for simple auth, add this
to map in memory and POST a file see answer here
Note, you will eventually want some kind of async http client for java , you can google for that. The apache examples like in the link provided are mostly blocking network calls AFAIK

Just need someone familiar with HTTPClient to check over a piece of code

here are two little helper methods I have made for downloading files. I have had to mix and match different tutorials of the web to get what I have here.
Now is there anything that I have done blatantly wrong here?
public static InputStream simplePostRequest(URL url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost postMethod=new HttpPost(url.toExternalForm());
postMethod.setEntity(new UrlEncodedFormEntity(postData, HTTP.UTF_8));
HttpResponse response = httpclient.execute(postMethod);
HttpEntity entity = response.getEntity();
return entity.getContent();
}
public static InputStream simpleGetRequest(URL url, List<NameValuePair> queryString) throws ClientProtocolException, IOException {
Uri.Builder uri = new Uri.Builder();
uri.path(url.getPath());
for(NameValuePair nvp: queryString) {
uri.appendQueryParameter(nvp.getName(), nvp.getValue());
}
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpHost host = new HttpHost(url.getHost());
HttpResponse response = httpClient.execute(host, new HttpGet(uri.build().toString()));
HttpEntity entity = response.getEntity();
return entity.getContent();
}
I wouldn't expect a huge response to a such a vague question. Why not write a pair of unit tests to try your code out instead?
Anyway, the one thing that stands out for me based on my experience with HttpClient is that if subject to heavy load (large number of concurrent threads), your code seems unsafe - there seems to be no upper bound to the number of concurrent connections that could get created.
If you think this might be relevant in your case, you could try something like this:
class X {
private static final HttpClient httpClient;
static {
SchemeRegistry defaultRegistery = new DefaultHttpClient().getConnectionManager()
.getSchemeRegistry();
ThreadSafeClientConnManager connMgr = new ThreadSafeClientConnManager(defaultRegistery);
connMgr.setMaxTotalConnections(10);
connMgr.setDefaultMaxPerRoute(10);
httpClient = new DefaultHttpClient(connMgr);
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
}
public static InputStream simpleGetRequest(URL url, List<NameValuePair> queryString) throws ClientProtocolException, IOException {...}
public static InputStream simpleGetRequest(URL url, List<NameValuePair> queryString) throws ClientProtocolException, IOException {...}
}
... and just use the static httpClient in your methods instead of instantiating a new one every time.
I copied and modified this from some code I've written before, but don't consider this necessarily correct. The unit tests will be your friends here.
EDIT: With regards to your comment about mixing URL and the HttpClient library class NameValuePair (is this your concern?), why not just a Map<String, String> in the method signatures?

Categories