Get token from OKTA API - Java (plain) example - java

I've created an account on OKTA environment here.
I searched on the net, but I couldn't find any examples on how to get access token from OKTA API. I'm looking for some example in "plain" Java code. But if there is something in any SDK, I'll be happy.
I tried to create an HTTP request (POST), to /token endpoint. I've used cliend_id and client_secret - in body. I've also tried to put in into header as basic authentication (before that, I encoded client_id:client_secret with Base64), but I still getting unauthorized (401).

OK I have a solution. The problem was wrong configuration on OKTA.
For those who needs working example, I'll share my tested code (believe me, it works)
public String GetToken() throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create("https://YOUR_OKTA_DOMAIN/oauth2/default/v1/token"))
.headers("Content-type", "application/x-www-form-urlencoded",
"Authorization", "Basic " + Base64.getEncoder().encodeToString("CLIENT_ID:CLIENT_SECRET".getBytes()),
"Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
"&grant_type=client_credentials" ))
.build();
HttpResponse<?> response = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());
return response.body().toString();
}
On Okta you need to have created additional scope for Authorization Server. This scope should be default, or if you don't want to set default scope, you have to add it in body as
.POST(HttpRequest.BodyPublishers.ofString(
"&grant_type=client_credentials" +
"scope=SCOPE_NAME"))

Related

how to create client TGT with java cxf

I'm new to the java rest CXF client. I will make various requests to a remote server, but first I need to create a Ticket Granting Ticket (TGT). I looked through various sources but I could not find a solution. The server requests that I will create a TGT are as follows:
Content-Type: text as parameter, application / x-www-form-urlencoded as value
username
password
I create TGT when I make this request with the example URL like below using Postman. (URL is example). But in the code below, I'm sending the request, but the response is null. Could you help me with the solution?
The example URL that I make a request with POST method using Postman: https://test.service.com/v1/tickets?format=text&username=user&password=pass
List<Object> providers = new ArrayList<Object>();
providers.add(new JacksonJsonProvider());
WebClient client = WebClient.create("https://test.service.com/v1/tickets?format=text&username=user&password=pass", providers);
Response response = client.getResponse();
You need to do a POST, yet you did not specify what your payload looks like?
Your RequestDTO and ResponseDTO have to have getters/setters.
An example of using JAX-RS 2.0 Client.
Client client = ClientBuilder.newBuilder().register(new JacksonJsonProvider()).build();
WebTarget target = client.target("https://test.service.com/v1/tickets");
target.queryParam("format", "text");
target.queryParam("username", "username");
target.queryParam("password", "password");
Response response = target.request().accept(MediaType.APPLICATION_FORM_URLENCODED).post(Entity.entity(yourPostDTO,
MediaType.APPLICATION_JSON));
YourResponseDTO responseDTO = response.readEntity(YourResponseDTO.class);
int status = response.getStatus();
Also something else that can help is if you copy the POST request from POSTMAN as cURL request. It might help to see the differences between your request and POSTMAN. Perhaps extra/different headers are added by postman?
Documentation: https://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-JAX-RS2.0andCXFspecificAPI
Similar Stackoverflow: Is there a way to configure the ClientBuilder POST request that would enable it to receive both a return code AND a JSON object?

How to follow-through on HTTP 303 status code when using HttpClient in Java 11 and later?

When using the java.net.http.HttpClient classes in Java 11 and later, how does one tell the client to follow through an HTTP 303 to get to the redirected page?
Here is an example. Wikipedia provides a REST URL for getting the summary of a random page of their content. That URL redirects to the URL of the randomly-chosen page. When running this code, I see the 303 when calling HttpResponse#toString. But I do not know how to tell the client class to follow along to the new URL.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest
.newBuilder()
.uri( URI.create( "https://en.wikipedia.org/api/rest_v1/page/random/summary" ) )
.build();
try
{
HttpResponse < String > response = client.send( request , HttpResponse.BodyHandlers.ofString() );
System.out.println( "response = " + response ); // ⬅️ We can see the `303` status code.
String body = response.body();
System.out.println( "body = " + body );
}
catch ( IOException e )
{
e.printStackTrace();
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
When run:
response = (GET https://en.wikipedia.org/api/rest_v1/page/random/summary) 303
body =
Problem
You're using HttpClient#newHttpClient(). The documentation of that method states:
Returns a new HttpClient with default settings.
Equivalent to newBuilder().build().
The default settings include: the "GET" request method, a preference of HTTP/2, a redirection policy of NEVER [emphasis added], the default proxy selector, and the default SSL context.
As emphasized, you are creating an HttpClient with a redirection policy of NEVER.
Solution
There are at least two solutions to your problem.
Automatically Follow Redirects
If you want to automatically follow redirects then you need to use HttpClient#newBuilder() (instead of #newHttpClient()) which allows you to configure the to-be-built client. Specifically, you need to call HttpClient.Builder#followRedirects(HttpClient.Redirect) with an appropriate redirect policy before building the client. For example:
HttpClient client =
HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.NORMAL) // follow redirects
.build();
The different redirect policies are specified by the HttpClient.Redirect enum:
Defines the automatic redirection policy.
The automatic redirection policy is checked whenever a 3XX response code is received. If redirection does not happen automatically, then the response, containing the 3XX response code, is returned, where it can be handled manually.
There are three constants: ALWAYS, NEVER, and NORMAL. The meaning of the first two is obvious from their names. The last one, NORMAL, behaves just like ALWAYS except it won't redirect from https URLs to http URLs.
Manually Follow Redirects
As noted in the documentation of HttpClient.Redirect you could instead manually follow a redirect. I'm not well versed in HTTP and how to properly handle all responses so I won't give an example here. But I believe, at a minimum, this requires you:
Check the status code of the response.
If the code indicates a redirect, grab the new URI from the response headers.
If the new URI is relative then resolve it against the request URI.
Send a new request.
Repeat 1-4 as needed.
Obviously configuring the HttpClient to automatically follow redirects is much easier (and less error-prone), but this approach would give you more control.
Please find below code where i was calling another api from my REST APi in java.
To note I am using java version 17. This will solve error code 303.
#GetMapping(value = "url/api/url")
private String methodName() throws IOException, InterruptedException {
var url = "api/url/"; // remote api url which you want to call
System.out.println(url);
var request = HttpRequest.newBuilder().GET().uri(URI.create(url)).setHeader("access-token-key", "accessTokenValue").build();
System.out.println(request);
var client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
System.out.println(client);
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response);
System.out.println(response.body());
return response.body();
}

407 Proxy Authentication error - Unirest Java 8

Hi everyone i'm so hopeless so ask you guys.
I'm trying to do a simple HTTP request but with my proxies I get 407 error code.
I use Unirest and Java 8.
Unirest.config().proxy(host, port, usernameProxy, passwordProxy);
HttpResponse<JsonNode> response = Unirest.post(url).asJson();
String body = response.getBody().toString();
That's it, my url is private but i wrote it like this: "https://myurl.com/?param1=param&param2....
It works proxyless but i'm stuck with proxies.
Thanks a lot
Seems like the proxy server expects for the proxy credentials within the Headers, which Unirest doesn't seem to propagate.
The header must specifically contain the "Proxy-Authorization" key in order to the handshake be even started.
String proxyCred= "user:password";
String baseCred= Base64.getEncoder().encodeToString(proxyCred.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.add("Proxy-Authorization", "Basic " + baseCred); // the proxy server needs this
This solution uses the Basic mechanism; It may not work, as the proxy may expect another type of authentication. You'll know which one is by reading the Proxy-Authenticate header within the server's response.
If the communication is not secured (HTTP and not HTTPS), you could read the response by sniffing the packet with some tool such as WireShark. Once you locate the 407 packet, you could read inside the Proxy-Authenticate value and modify your authorization method according do it.

How to build logout request using okhttp?

I am using Simple_JWT for authentication in Djangorestframework back-end. when a user is logged in the following url will log them out:
http://130.50.85.130/rest-auth/logout/
it requires no data.
now I am trying to post similar request using Okhttp.
When I am trying the following, it breaks:
Request post_request = new Request.Builder()
.url(url_str)
.addHeader("Authorization", "JWT "+token)
.build();
Note that it doesn't have a body and it has token in the header. I am not sure if this post request needs any body or needs header containing token.
I guess the bottom line of my question is how to send a request for log out using okhttp from a user that is already signed in,
Please advise,
Thanks,

Request working fine in postman, but getting a 403 in OkHTTP

I'm trying to make a request to the Genius API, but I'm running into some issues using OkHTTP. This is my small script I'm using to make the call:
public class OkHttpScript {
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.header("Authorization", "Bearer uDtfeAgTKL3_YnOxco4NV6B-WVZAIGyuzgH6Yp07FiV9K9ZRFOAa3r3YoxHVG1Gg")
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
public static void main(String[] args) throws IOException {
OkHttpScript okHttpScript = new OkHttpScript();
String response = okHttpScript.run("http://api.genius.com/songs/378195/");
System.out.println(response);
}
}
When I run this script, I get a 403 error:
{"meta":{"status":401,"message":"This call requires an access_token. Please see: https://genius.com/developers"}}
For reference, here is a picture of me making the same exact request with Postman, and it works:
Any ideas on what the problem could be?
Edit:
Not sure if this is normal, but when I print out my request object that gets built, I see no indication that there are headers in the request:
Request{method=GET, url=http://api.genius.com/songs/378195/, tag=null}
Is what I get. Could this be part of the problem?
Edit2:
Nevermind, doing a
System.out.println(newRequest.headers());
gives me what I originally put in:
Authorization: Bearer 4mfDBVzCnp2S1Fc0l0K0cfqOrQYjRrb-OHi8W1f-PPU7LNLI6-cXY2E727-1gHYR
So I figured out what my problem was. I'm not sure of the details behind it, but I should have been using my URL has https://api.genius.com/songs/378195/ instead of http://api.genius.com/songs/378195/
Postman seems fine with the http, but OkHttp needed https.
Not sure how your server side is written, I had the same problem today when requesting someone else's service. My solution was to change the User-Agent, even if PostmanRuntime/7.26.10
You should add an interceptor for okhttp something like this should work
How to handle auth0 403 error without adding specific code everywhere (Retrofit/okhttp/RxAndroid)
*Used Alex Hermstad Answer
--> Use https instead of http in android ,
Postman seems fine with the http, but OkHttp needed https.
I was stuck for a day for this error 403 forbidden in android , but giving 200 success in Postman .

Categories