Java OAuth 2.0 get access token - java

I want to get access token OAuth 2.0 from REST API via Java code, the thing is that I've managed to successfully get it back from the server with Bash script (curl command)
Bash script (working):
#!/usr/bin/env bash
# Base URL of TeamForge site.
site_url="https://teamforge.example.com"
# TeamForge authentication credentials.
username="foo"
password="bar"
# Requested scope (all)
scope="urn:ctf:services:ctf
curl -d "grant_type=password&client_id=api-client&scope=$scope&username=$username&password=$password" $site_url/sf/auth/token
With that code snippet I'got this response:
{
"access_token": "eyJraWQiOiIxIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF1ZCI...",
"token_type": "Bearer"
}
When I've tried to translate it to Java code using Unirest :
HttpResponse<JsonNode> jsonResponse = Unirest.post("\"https://teamforge.example.com/sf/auth/token")
.header("accept", "application/json")
.body("{\"grant_type\":\"password\"," +
"\"client_id\":\"api-client\", " +
"\"scope\":\"urn:ctf:services:ctf\"," +
"\"username\":\"foo\"," +
"\"password\":\"bar\"}")
.asJson();
System.out.println(jsonResponse.getBody());
Response was:
{"error_description":"Invalid grant","error":"invalid_grant"}
After a couple of researches and tries, I still don't know what am I missing in my Java code request. Can someone help me to add missing stuff or guide me to right directions?
CollabNet docs:
Saso

Please try:
JsonNode jsonResponse = Unirest.post("https://teamforge.example.com/sf/auth/token")
.header("Content-Type", "application/json")
.field("scope", "urn:ctf:services:ctf")
.field("client_id", "api-client")
.field("grant_type", "password")
.field("username", "foo")
.field("password", "bar")
.asJson()
.getBody();
And one more question are you sure about grant type ?
grant_type = client_credentials maybe you need something like this.

Related

Adding an authentication token to header in Restlet

I am trying to make an API call using Restlet in java however when I run my code I get an org.restlet.resource.ResourceException: Unauthorized (401) - The request requires user authentication
The format for the API call is as follows for shell: curl "<api_url>" \ -H "Authorization: Bearer <api_token_here>"
However I am unsure how to add this authorization header in Restlet, as you are not able to add the header using .getRequest().getHeaders().add();
Additionally I have tried to set a challenge response however this also does not appear to work.
API = new ClientResource(RequestURL);
API.setProtocol(Protocol.HTTPS);
ChallengeResponse AuthHeader = new ChallengeResponse(ChallengeScheme.CUSTOM);
AuthHeader.setRawValue("Authorization: Bearer " + APIKey);
API.getRequest().setChallengeResponse(AuthHeader);
API.get();
I appear to have solved the issue with the following code:
ChallengeResponse AuthHeader = new ChallengeResponse(ChallengeScheme.HTTP_OAUTH_BEARER);
AuthHeader.setRawValue(APIKey);
AuthHeader.setIdentifier("Bearer");
API.setChallengeResponse(AuthHeader);

Spring Boot REST API unrecognized token

I have a REST API and a WEB-app that makes request for that API. Both in Spring Boot.
I followed one of the many guides on this and testing the API in postman worked fine.
I also tested the API from my webapp and it also worked.
But when i run my API in docker with Traefik i get an error, but only from the webapp. Postman still works fine.
2020-10-27T13:31:10.334026053Z at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na],
2020-10-27T13:32:34.827929610Z java.lang.RuntimeException: Could not read
requestcom.fasterxml.jackson.core.JsonParseException: Unrecognized token 'ssword': was expecting
(JSON String, Number, Array, Object or token 'null', 'true' or 'false')
In the request i post username and password as json in the body like this:
{
"username" : "user",
"password" : "dfgdhghdhdhfd"
}
This is the code that generates the request from the webapp:
JsonObject j = new JsonObject();
j.addProperty("username", API_USER);
j.addProperty("password", API_PASSWORD);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://myapi.local/login"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(j.toString()))
.timeout(Duration.ofSeconds(2L))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
return response.headers().firstValue("Authorization").get();
Is there any chance it gets truncated somehow as it refers to the latter half of the 'password' key? I'm unsure of even where to begin getting information to assist you in helping me.
To summarize:
Localhost webapp and postman to localhost API: Works
Localhost postman to Docker API: Works
Localhost webapp to Docker API: Does not work

Using Vert.x Web Client to send GET requests properly with headers

I have an internal endpoint that I am trying to send GET requests to with Vert.x Web Client with Java. So far, I am unable to successfully get any data back.
If I cURL the endpoint, it works just fine (these are internal endpoints). The service I am trying to send GET requests to requires a few headers , and data as well:
curl -H "Accept:application/json" -H "Content-Type:application/json" -H "alpha:192.168.10.20" -d '{"mutate":"*"}' http://my-endpoint.com/api/get-items
But if I try to use this in one of my router endpoints in Vert.x, I get an error:
WebClient webClient = WebClient.create(vertx);
webClient.get("http://my-endpoint.com/api/get-items")
.putHeader("Accept", "application/json")
.putHeader("Content-Type", "application/json")
.putHeader("alpha", "192.168.10.20")
.sendJsonObject(new JsonObject().put("mutate", "*"), ar -> {
if (ar.succeeded()) {
System.out.println("##### WEBCLIENT #####");
System.out.println(ar);
} else {
System.out.println("CAUSE: " + ar.cause().getMessage());
}
});
The error message I get from the else statement is:
CAUSE: Connection refused: localhost/127.0.0.1:80
What am I doing wrong? I've been using this for reference: Vert.x Web Client
===========================================
SOLUTION
===========================================
I had to change
webClient.get("http://my-endpoint.com/api/get-items")
to
webClient.post(80, "my-endpoint.com", "/api/get-items")
Also had to add .as(BodyCodec.jsonArray()) underneath the above line because the result I was getting was a Json Array.
You need to change
webClient.get("http://my-endpoint.com/api/get-items")
to
webClient.get(80, "my-endpoint.com", "/api/get-items")

Watson Natural Language Understanding Java 401-not authorized

I'm trying to connect my Java application to the Watson NLU service. For a start, I tried to follow the tutorial from Bluemix. I created a service on Bluemix and imported the watson Java SDK. Using this tutorial code, I keep receiving 401 - not authorized responses. (Of course i changed username and password for the service).
I guess there's something missing, but i can't figure out what.
NaturalLanguageUnderstanding service = new NaturalLanguageUnderstanding(
NaturalLanguageUnderstanding.VERSION_DATE_2017_02_27,
"{username}",
"{password}"
);
String text = "IBM is an American multinational technology " +
"company headquartered in Armonk, New York, " +
"United States, with operations in over 170 countries.";
EntitiesOptions entitiesOptions = new EntitiesOptions.Builder()
.emotion(true)
.sentiment(true)
.limit(2)
.build();
KeywordsOptions keywordsOptions = new KeywordsOptions.Builder()
.emotion(true)
.sentiment(true)
.limit(2)
.build();
Features features = new Features.Builder()
.entities(entitiesOptions)
.keywords(keywordsOptions)
.build();
AnalyzeOptions parameters = new AnalyzeOptions.Builder()
.text(text)
.features(features)
.build();
AnalysisResults response = service
.analyze(parameters)
.execute();
System.out.println(response);
i had the same problems in node.js and solved it by adding the correct url of the api gateway to the NaturalLanguageUnderstanding service = new NaturalLanguageUnderstanding() object.
please keep in mind, that this depends on your region ..
regards
Leo
A 401 Unauthorized would suggest that there's an issue with the credentials that you're using to access the service. To rule this out, take a start by using the cURL tutorial from that same page:
curl -X POST \
-H "Content-Type: application/json" \
-u "{username}":"{password}" \
-d #parameters.json "https://gateway.watsonplatform.net/natural-language-understanding/api/v1/analyze?version=2017-02-27"
If, with that same username and password, you still receive a 401 Unauthorized error, then there's likely an issue with that username/password combination. Delete the tile in Bluemix and create a new one to get a new username/password, and give that a try.
If that does work fine, then there's an issue with how the username/password is being inserted into the code. Verify that you've replaced {username} and {password}, the final version should not have any curly brackets in it.

JSON in a POST request is unsupported for Restlet

We're creating small project in which we have flask as a FrontEnd and restlet based WebService.
We try to send login data as a JSON from flask to restlet:
def login():
error = None
if request.method == 'POST':
payload = {'username' : request.form['username'], 'password' : request.form['password']}
headers = {'Content-Type': 'application/json'}
req = requests.post(WEBSERVICE_IP + '/login', data=json.dumps(payload), headers=headers)
(...)
Flask based website is shouting about:
ValueError: No JSON object could be decoded
We have no idea how to reconcile communication between flask and restlet.
Edit (22-04 10:08pm GMT):
I found out that responce was:
<html>
(...)
Unsupported Media Type
The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method
(...)
</html>
Edit (22-04 11:26pm GMT):
I'm still not sure why, but I supposed that it may be something with JSON format. After correcting my code so it will send correct JSON (said JSONLint), I still get the same messages. Anyone know how to create JSONObject in Python? WebService have method:
#Post("json")
public JSONObject verifyAccount(JSONObject dane){
Edit (23-04 7:26pm GMT):
Ok. So we're almost sure that it's problem with invisible header. Can anyone confirm that header creation in python code here is correct?
Edit (24-04 5:40pm GMT):
Problem is still actual. As some other suggested, I changed requests back to the urllib2. This helped with the first thing - "Value problem". Now browser is having
urllib2.HTTPError
HTTPError: HTTP Error 415: Unsupported Media Type
POST Request now:
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
payload = {"Login": request.form['username'],
"Haslo": request.form['haslo']}
data = json.dumps(payload)
clen = len(data)
req = urllib2.Request(WEBSERVICE_IP + '/login', data,
{'Content-Type': 'application/json', 'Content-Length': clen})
f = urllib2.urlopen(req)
response = f.read()
f.close()
Edit (24-04 6:20pm GMT):
Wireshark captured POST request and it looks ok.
If data is a dictionary, Requests will serialize it. You want to pass a string instead:
import json
req = requests.post(WEBSERVICE_IP + '/login', data=json.dumps(payload), ...
Ok. Solution was easier than I would think.
Problem was on the WebService side. It was resolved by changing JSONObject to JsonRepresentation:
#Post("json")
public JSONObject verifyAccount(JsonRepresentation data){
In addition to Blender's point (which is a much more likely culprit), it's worth mentioning that content-type ought to be set to application/json rather than json.
To add on Hazards response, I had to edit #Post("json") to #Post("application/json"):
#Post("application/json")
public JSONObject verifyAccount(JsonRepresentation data){

Categories

Resources