How to get token in java - java

I have the following implementation to get token from form authentication.
The expected output is as follows:
However, when I run my implementation, I am getting as follows. In the response object, I do not see token. I am not an expert on Java, I wonder what I am missing.
Login form get: HTTP/1.1 200 OK
response: HttpResponseProxy{HTTP/1.1 200 OK [Cache-Control: max-age=0, Content-Type: application/json, Date: Fri, 04 Aug 2017 21:05:04 GMT, transaction_id: 729097fd-69ac-b813-26c7-015daf10ddfd, X-Powered-By: Express, Content-Length: 684, Connection: keep-alive] ResponseEntityProxy{[Content-Type: application/json,Content-Length: 684,Chunked: false]}}
Post logon cookies:
None
Here is the source code:
BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.build();
HttpHost proxy = new HttpHost("xxx.xxx.xxx.com", 80, "http");
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build();
HttpUriRequest login = RequestBuilder.post()
.setUri(new URI("https://api.xxx.com:443/tokens"))
.addParameter("username", "stackoverflow")
.addParameter("password", "isbest!")
.setConfig(config)
.build();
CloseableHttpResponse response2 = httpclient.execute(login);
HttpEntity entity = response2.getEntity();
System.out.println("Login form get: " + response2.getStatusLine());
EntityUtils.consume(entity);
System.out.println("response: " + response2);
System.out.println("Post logon cookies:");
List<Cookie> cookies = cookieStore.getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}

When you call EntityUtils#consume(HttpEntity), you are fully consuming the content of the response and closing the underlying stream. However, you haven't actually read the response data into any variable accessible by your code, so you no longer have any opportunity to look at it.
Instead, call one of the methods that fetches the response data. Options for this include HttpEntity#getContent() to access the response body as a raw InputStream or EntityUtils#toString(HttpEntity, Charset) to read the whole response body as a String. (In the latter case, be aware that reading the whole response body at once as a String will impact your process's memory footprint if the response body is large.) After calling either one of those, you can pass the retrieved content through your JSON parser of choice to retrieve the "token".
Once you're all done, it's still good practice to call EntityUtils#consume(HttpEntity) to guarantee cleanup of any underlying resources encapsulated by the entity, such as streams.

Related

415 error while calling post API from jersey client

I have below API which returns back the access_token.
POST https://idcs-xxxxxxxxxbf08128c3d93a19c.identity.c9dev2.oc9qadev.com/oauth2/v1/token
in header content-type is application/x-www-form-urlencoded. also in body it contains below parameter.
I send user name and password and it is secured with basic authentication. It provides access_token when I call from postman. also it provides output when I consume using HttpUrlConnection
url = new URL(tokenURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Authorization", auth);
connection.setRequestProperty("Accept", "application/json");
OutputStream os = connection.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
osw.write("grant_type=client_credentials&scope=" + scope);
The above code is working properly. But when I use jersey it gives 415 error. I am using below code.
String user="idcs-oda-zzzxxxxxf93560b94eb8a2e2a4c9aac9a3ff-t0_APPID";
String password="xxxxxxx-6f71-4af2-b5cc-9110890d1456";
String scope = "https://idcs-oda-xxxxxxxxxxxxxxxxe2a4c9aac9a3ff-t0.data.digitalassistant.oci.oc-test.com/api/v1";
String tokenURL = "https://idcs-xxxxxxxxxxxxxxxx28c3d93a19c.identity.c9dev2.oc9qadev.com/oauth2/v1/token";
HttpAuthenticationFeature feature= HttpAuthenticationFeature
.basicBuilder()
.nonPreemptive()
.credentials(user,password)
.build();
ClientConfig clientConfig = new ClientConfig();
clientConfig.register(feature);
Client client = ClientBuilder.newClient(clientConfig);
WebTarget webTarget= client.target(tokenURL);
PostDetails post= new PostDetails("client_credentials",scope); //Bean class to assign body parameter
Response response= webTarget.request()
.header("Content-Type", "application/x-www-form-urlencoded")
.post(Entity.json(post));
System.out.println(response);
Can somebody tell me what mistake I am doing in Response line.
You need to set your Accept on the request method:
Response response= webTarget.request(MediaType.APPLICATION_JSON)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(Entity.json(post));
You also need to ensure that if your API accepts application/x-www-form-urlencoded content, that is what you are sending.
Currently, you are sending application/json content based on your usage of Entity.json(post).
I don't know what type is assigned to post, but you need to figure out how to convert it either to a Form or a MultiValuedMap<String,String>, and then use the form method on Entity to submit your content.
Response response= webTarget.request(MediaType.APPLICATION_JSON)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(Entity.form(postForm)); //assuming postForm typed as Form or MultiValuedMap<String,String>
Taking a guess regarding post, creating postForm as a MultiValuedMap<String,String> may be as simple as the following (which you would place prior to your request, of course).
MultiValuedMap<String,String> postForm = new MultiValuedHashMap<>();
postForm.add("client_credentials",scope);
What you need is:
Response response= webTarget.request()
.accept("application/json") // Accept field from header of request
.header("Content-Type", "application/x-www-form-urlencoded") //manually set content-tyoe
.post(Entity.entity(input, MediaType.TEXT_PLAIN)); // request body
The best way to see what is Jersey actually is sending is to register logger, and log network. For example:
clientConfig.register(
new LoggingFeature(
new Slf4jLogger(this.getClass().getName(), null)));
where Slf4jLogger is from org.apache.cxf:cxf-core.

Got 404 when posting attachment to confluence with Java and Apache HttpClient

I am trying to post images to an confluence page as attachment to a content.
Here is the function of my java application:
public void postAttachment(File f, String comment) throws IOException {
if (!f.exists() || !f.canRead()) {
throw new IOException("Could not access file " + f.getAbsolutePath());
}
final FileBody bin = new FileBody(f);
final StringBody cmt = new StringBody(comment, ContentType.TEXT_PLAIN);
final HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("file", bin).addPart("comment", cmt).build();
final HttpPost post = new HttpPost(baseUrl + "/rest/api/content/" + contentid + "/child/attachment");
post.setEntity(reqEntity);
post.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials(props.getString("confluence_user"),props.getString("confluence_password")), "UTF-8", false));
post.addHeader("X-Atlassian-Token:","no-check");
System.out.println("executing request " + post.getRequestLine());
final CloseableHttpClient httpclient = HttpClients.createDefault();
final CloseableHttpResponse response = httpclient.execute(post);
System.out.println(post.getRequestLine());
System.out.println(response.toString());
if (response.getStatusLine().getStatusCode() == 404) {
throw new IOException("Status 404 thrown!");
}
}
The output in the terminal is:
POST https://xxx.xxxx.de:443/rest/api/content/38262140/child/attachment
and then
HttpResponseProxy{HTTP/1.1 404 Not Found [Server: Apache-Coyote/1.1, X-ASEN: SEN-1343236, Set-Cookie: JSESSIONID=9DF46011711C2828977E17A945D023E1; Path=/; Secure; HttpOnly, X-Seraph-LoginReason: OK, X-AUSERNAME: xxxx, X-Content-Type-Options: nosniff, Content-Type: text/plain, Transfer-Encoding: chunked, Date: Tue, 27 Sep 2016 11:20:35 GMT] ResponseEntityProxy{[Content-Type: text/plain,Chunked: true]}}
(I changed the domain name and username just for this post..)
So all seems ok. If i copy the generated POST url and do a GET in the browser i get a json snippet with an attachment list, manually uploaded before. So the POST url should be ok.
I searched across the web but i cant find where i am wrong with my code.. Any Suggestions?
Confluence is strict in "X-Atlassian-Token" header value. You have extra : in header name.
Change
post.addHeader("X-Atlassian-Token:","no-check");
to
post.addHeader("X-Atlassian-Token","no-check");
This will create correct header, and 404 error will go away
I too am presently struggling to add attachments; now on to a 403 Forbidden...
I worked through my 404 finding that it was in my (bad) URL. However, your URL does appear correct. Any chance that Page ID is off or your authenticated user lacks permissions (globally, in the space, or at the page level)?
Edit: Oh! And, as mtheriault's post suggests, check the attachment size vis a vis your Confluence instance's "attachmentMaxSize".

Java httpget seems to work but encountering 401 error

HAve re-written due to the feedback so far...
I'ev got a Java method to try and download a file via httpget within a selenium script, it looks like so...
private String downloader(WebElement element, String attribute, String filePath) throws IOException, NullPointerException, URISyntaxException {
String fileToDownloadLocation = element.getAttribute(attribute);
fileToDownloadLocation = fileToDownloadLocation.replace("\\", "%5C");
URL fileToDownload = new URL(fileToDownloadLocation);
URI FileDL = new URI(fileToDownload.toString());
File downloadedFile = new File(this.localDownloadPath + filePath);
if (downloadedFile.canWrite() == false) downloadedFile.setWritable(true);
CloseableHttpClient httpclient = HttpClients.createDefault();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,new NTCredentials("useraccount", "testpassword", "machinename", "mydomain"));
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
HttpGet httpget = new HttpGet(FileDL);
CloseableHttpResponse response = httpclient.execute(httpget, context);
this.httpStatusOfLastDownloadAttempt = response.getStatusLine().getStatusCode();
FileUtils.copyInputStreamToFile(response.getEntity().getContent(), downloadedFile);
response.getEntity().getContent().close();
String downloadedFileAbsolutePath = downloadedFile.getAbsolutePath();
return downloadedFileAbsolutePath;
}
When I use this on a regular link (i.e. downloading a file from the bbc for example) it all works. The trouble is the system I'm using it on is an internal one that uses windows authentication to determine if access is permitted. When I attempt to use it on this internal system my Http response ends up reading: -
HTTP/1.1 401 Unauthorized [Cache-Control: no-cache, no-store, must-revalidate, Pragma: no-cache, Content-Type: text/html, Expires: -1, Server: Microsoft-IIS/7.5, WWW-Authenticate: Negotiate, WWW-Authenticate: NTLM, X-Powered-By: ASP.NET, X-UA-Compatible: IE=edge, Date: Mon, 17 Mar 2014 14:52:43 GMT, Content-Length: 1293]
If I debug this and obtain the URL it uses I can manually paste this into a browser and it works fine.
I also noticed that during debug the httpRequestParameters doesn't seem to have any values in in at all (shows as null) so I'm guessing that I'm still not setting the account parameters properly somehow.
I'll be honest and say I'm really not 100% on what all this does properly and am trying to paste things together and get it to play ball but I'm wondering if the section where I have ((AbstractHttpClient) client).getCredentialsProvider(). is set up properly or if I'm missing something here...
Any further help much appreciated!
You can set the BASIC authentication credentials in two different ways:
Setting the appropiated HTTP header:
HttpClient hc = new DefaultHttpClient();
HttpGet get = new HttpGet("http://...");
String basic_auth = new String(Base64.encodeBase64((username + ":" + password).getBytes()));
get.addHeader("Authorization", "Basic " + basic_auth);
or using the CredentialsProvider (depends on the Apache HttpComponents version)
HttpClient hc = new DefaultHttpClient();
hc.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("username", "password"));
HttpGet get = new HttpGet ("http://...");
hc.execute(get);
I've finally managed to get my code working, the final version is shown above. I'd made a few obvious errors such as my domain was still set to the examples "microsoft.com" and I had actually misspelled my password, other than that it now does exactly what I need it to! :)
#vzamanillo thanks for your help!

How to read in a Java client a response from servlet?

I have a Java application :
-this application send a String :
HttpClient httpClient = new DefaultHttpClient();
try {
HttpPost request = new HttpPost(url);
StringEntity params = new StringEntity(xml);
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
// handle response here...
String res= response.toString();
System.out.println("RESPONSE=>\n"+response); //where i read the response
} catch (Exception ex) {
// handle exception here
} finally {
httpClient.getConnectionManager().shutdown();
}
I work with this String in my servlet and I just want to send a String response.
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("TEST");
But when i read the response i just have my header:
RESPONSE=>
HTTP/1.1 200 OK [X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2.2 Java/Oracle Corporation/1.7), Server: GlassFish Server Open Source Edition 3.1.2.2, Content-Type: text/html;charset=UTF-8, Content-Length: 83, Date: Fri, 14 Dec 2012 17:17:07 GMT]
Someone can help me ?
You are using the wrong method to read your response date. Calling:
String res= response.toString();
Just gives you the string representation of the Response object, not the data it contains. The Apache Http Commons library has a utility class that makes it easy to read responses, called EntityUtils. Use this instead to read the entire response body. Don't forget that you need to verify that the request actually completed successfully before doing this:
if(response.getStatusLine().getStatusCode() == 200) {
final String res = EntityUtils.toString(response.getEntity());
}

Apache HttpClient not receiving all cookies?

I posted before but now I seem to actually see the problem, just having trouble fixing it.
I am trying to login to my schools grade website, maybe even make an app for it later, and when I use Chrome to inspect the cookies being created, I get all these,
Cookie:appName=chippewa_falls; tool=""; selection=""; districtID=1; endYear=2011; calendarID=0; permCalendarID=0; JSESSIONID=BE5AEF51EAA72975150FC2D0F77DDE13
But when my program prints all the cookies it received, I only get this
[version: 0][name: JSESSIONID][value: BC1BAA33BEB23DC27B7883AC24934A1D][domain: campus.chipfalls.k12.wi.us][path: /campus][expiry: null]
here is my code,
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("https://campus.chipfalls.k12.wi.us/campus/portal/chippewa_falls.jsp");
httpget.addHeader("Referer", "http://cfsd.chipfalls.k12.wi.us//high/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
InputStream input = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String ln = "";
while((ln = reader.readLine()) != null) {
System.out.println("During Get - " + ln);
}
}
System.out.println("Initial set of cookies:");
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
Note that is just for the GET part of it,
Thanks for any help :)
Edit: I did forget to mention, it is using HTTPS, but to be honest, I don't know if that matters with apache client or not.
Those cookies must be getting set AFTER you login, not before. Looking at the output with wget of the URL you have above you see this:
Resolving campus.chipfalls.k12.wi.us... 205.213.253.11
Connecting to campus.chipfalls.k12.wi.us|205.213.253.11|:443... connected.
WARNING: Certificate verification error for campus.chipfalls.k12.wi.us: self signed certificate in certificate chain
HTTP request sent, awaiting response...
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=004549BDBCBDFB8289EBF859A4E743B2; Path=/campus; Secure
Content-Type: text/html;charset=utf-8
Content-Length: 6352
Date: Tue, 17 May 2011 06:00:38 GMT
Connection: keep-alive
Length: 6,352 (6.2K) [text/html]
which is the exact same thing you see. Until you actually log in you will not see the other cookies.

Categories

Resources