Unable to exchange OAuth auth code for access token - java

I'm just trying to make a simple app, but I can't even get past authenticating the user. I am using the Google OAuth Client Library for Java.
These are the current steps I am taking:
Start local web server to listen for the loopback response after the OAuth authentication.
Generate the auth URL:
String url = new AuthorizationCodeRequestUrl(AUTH_URL, CLIENT_ID)
.setScopes(scopes) // Contains https://www.googleapis.com/auth/drive.readonly
.setRedirectUri(LOCALHOST + r.getPort()) // Port of local web server
.build();
Use URL to authenticate account.
Google returns auth code.
Exchange auth code for access token.
TokenResponse token = new AuthorizationCodeTokenRequest(...)
.setRedirectUri("http://localhost") // <--
.setClientAuthentication(getClientAuth()) // ClientParametersAuthentication object
.execute();
This is where my problem occurs. No matter what value I put in for redirect_uri, I always get {"error":"redirect_uri_mismatch","error_description":"Bad Request"} in return.
Searching Google for the error, every single result says that it's because the redirect_uri I sent is not registered in the API console.
When I download the credentials json file, the redirect_uris section contains "urn:ietf:wg:oauth:2.0:oob","http://localhost", but it's all the same error no matter what I put in.
I went to the Credentials section of the project to fix it, but since this is an installed application, creating credentials for the project gives me no option to set any redirect uris. The only way to get access to changing redirect_uris are to create the credentials for "Web application," but this isn't a web application and I don't have a domain it can redirect to.
So I'm stuck, redirect_uri options are not available to me and no value that I use works, I honestly don't know what else to try. What steps can I take to fix this?

It turns out that the same redirect_uri must be used for the auth code and access token even if it's not going to be used for retrieving the access token.

Related

Retrieve Oauth2 Authorization code and Access token through API 2022 Implementation

Based on the diagram you can see above (Oauth authrization flow). Reference https://youtu.be/oKzeHshquCs?t=1949
Using user credentials (username, password), we are attempting to
get an authorization code (login).
Authorization code received.
Using the received authorization code we are now requesting an
access token.
When access token is given. This access token will be
now used to access the resource server (as Bearer Token).
I would like to ask how to implement this using API, using the latest implementation of OAuth2. Using custom REST API's on the Authorization Server.
Scenario: using two api's ('/auth/code' then ''auth/token'')
Using user credentials (username, password) the user will request on
api '/auth/code', where authorization_code as the response.
Using the recieved authorization code (from #1), we will request an access
token on '/auth/token'. Access token will be used as bearer token on
the authorization server.
Or if we can do this two step (#1 and #2 above) on one API process (auth/token) would also be great.
Do you have any working project in regards with this?
I have explored the code of Baeldung, but based on this implementation, it is still using the default implementation of spring security. It would be my great pleasure if there are Senpai's out there can help me with this. Thanks :)
There's no such API to get an authorization code directly passing the user credentials. Usually, there would be an API (/as/authorization), which redirects the user to the login page. Once the user enters his credentials, he will be redirected to the target application with the authorization code in code as the query parameter of the URL. (You need to configure your app's URL as a redirect URL or callback URL in the Identity provider)
This code is usually short-lived and can't be used more than a time. (i.e) You can use this code only once to get an access token. When you exchange the code with an access token, you should be seeing refresh_token (if you granted access to refresh_token grant_type in the IdP) as well with which you can request tokens in the future.
You need to configure all these things in an Identity Provider. This could be PingIdentity, Auth0, etc.
Make a call to /as/authorization API
Once user enters his credentials and redirected to the target application, extract the code from the query parameter and make a call to token API (oauth/token) to get access_token and refresh_token
Once the access_token is expired, use the refresh_token to get a new access_token (grant_type should be refresh_token).
Once the refresh_token is expired, you need to again get the authorization_code again with the /as/authorization API.

Spring Boot OAuth2 - Remember given Authorization

i'm currently working on a OAuth2 Authorization Server using Spring Boot and the Spring Security OAuth2 Autoconfigure library.
Everything works so far except the fact that I need to authorize the client every time to access my protected resources. Is there any way to suppress the prompt or remember that i've already authorized the client?
Adding &prompt=none to the request params of my URL didn't work as expected.
I already tried to add a custom AuthorizationRequestResolver and adding prompt=none to every request, but that didn't work also.
Thank you in advance.
Usually after you are authorized by the authorization server, as a result you get an access token.
The resource server verifies against the access token to determine your client has the right to retrieve the requested resources.
With this background, one possible case is that:
Your client doesn't store the access token. So that everytime it hits the resource server, the resource server redirects the client to the authorization server to get the access token.
A solution of this is your client can store the access token. For the subsequent requests to the resources server, the access token has to be provided in an expected way. (like Aurthorization request header)
You may also find storing a refresh token is useful. Since there is no much background about your client app, cannot give a concrete recommendation for you.
If this is the case, you can log your outgoing request from the client to the resources server, you will see the access token missing in your request.

Is it possible to get authorization_code in OAuth 2.0 without web browser in Java?

As I understand, in authorization code flow we need to get authorization code and use it to get token after. We can get this code only when user confirms specified access. After that browser redirects us to redirect_uri and response will contain authorization code as parameter. So, the question: is it possible to get this authorization code without browser or any self made UI? Can we get it in application after correct request to, for example https://mysite.tuz/authorize ?
As you are using authorization code flow, the client requires a user agent (i.e browser or mobile app) to get the authorization code from the authorization server.
The whole purpose of using authorization code is that it can be passed via the user's web browser (user agent) instead of passing the access tokens directly via the web browser (user agent) which is not desired. Using authorization code,the Client then can directly retrieve an Access Token from the authorization server.
So the user agent is required to get the authorization code and act as an intermediary between client and authorization server.
If you do not require a browser then authorization code flow may not the correct choice. OAuth 2.0 supports several different grants i.e ways of retrieving an Access Token. Deciding which one is suited for your case depends mostly on your Client's type.
This might help you in deciding which flow to use
https://auth0.com/docs/api-auth/which-oauth-flow-to-use
You should use client credentials to obtain token without browser or any client. But if you need to use user credentials to get access token and id token of the user without browser or mobile app you need to implement you own client which will do the necessary logic for you and fetch the token for you. I already did it in java for the testing purpose. I don't know why you need to do it but you can implement your own client in almost any programming language . But in case you will decide to go this way you have to handle lot of things.
I expect your authorization server requires Proof-Key for Code
Exchange (PKCE) - so first of all before you start to communication
with server you have to create code verifier and code challenge
(google can help you with that :) in java it is quite simple)
Then you should start communication with server sending get request to url which ends with 'auth' you should send query params as: response_type (which is 'authorization_code' in your case), redirect_uri, client_id, code_verifier, code_challenge, scope, code_challenge_method (probably 'S256')
Then you receive I think two redirects from server so it is better to have some client in java which will automatically call those redirects. I used apache http client for my implementation. It has lot of features.
After successful redirect server will return login page to your client. It depends on authorization server but in this page you should put the data as username and password and submit the page. I have simply parsed the returned page and get the url for user authentication from it and simply make post request to that url with user credentials data sent in encoded form entity. In apache http client you will have all cookies from previous communication set (until you close the client) since apache http client automatically set all cookies returned in previous communication from server.
After make authentication request server will send you two redirects and you can store those redirects int http client context which you will provide for http client when you call authentication url.
In the last redirect there will be query parameter sent be server named "CODE" this is really important for you since you will use it to get token from the server
And finally you have to make one last post request to authorization server with url ended as token. So make a post request with GRANT_TYPE, REDIRECT_URI, CODE (you received in previous redirect), CLIENT_ID, CODE_VERIFIER (you have generated at the beginning);
Then authorization server will send you token and that's all

Retaining Google API authorization in desktop app

When connecting to the google services from a desktop app user is required to enter access code provided to him to generate accessToken.
I can't quite understand how to properly save it and restore into GoogleCredential so user wouldn't have to authorize my app on every launch.
Can somebody provide me with a code snippet of this process or a more detailed instruction than the one Google provides?
First you have to register your project into the Google Developer console. From the console your will get some credentials like: cliend id, client secrets.
Now when you want to authorize your application u need to get an access token. But before u have to get an "authorization token". For this u need to use an url like this
https://accounts.google.com/o/oauth2/auth?
redirect_uri=yourredirectpage&
response_type=code&
client_id=1070885696038-32m83k9ties5m7qsi4g6v8dfo28f2r9g.apps.googleusercontent.com&
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar&
approval_prompt=force&access_type=offline
The response of this request contains the authorization token. Now you can exchange the authorization token for the access token with another request:
https://accounts.google.com/o/oauth2/token?
code=4/oIdtdqPBW67CTSpijkm_fbwCqMjF_WJPiSmvsq8zScA.Ilw2ePhp3fQeoiIBeO6P2m_Usz4vlgI&
client_id=1070885696038-32m83k9ties5m7qsi4g6v8dfo28f2r9g.apps.googleusercontent.com&
client_secret={your_client_secret}&
redirect_uri=yourredirectpage&
grant_type=authorization_code
Where "code" is the authorization_token.
For more details check this: Google Api OAuth

restfb: Writing a facebook application with java (using the new graph api)

I'm trying to write a facebook application using Java tomcat with RestFB.
the restfb documentation shows the following:
Create a Facebook Application
Request https://graph.facebook.com/oauth/authorize?client_id=MY_API_KEY& redirect_uri=http://www.facebook.com/connect/login_success.html& scope=publish_stream,offline_access,create_event
Facebook will redirect you to http://www.facebook.com/connect/login_success.html? code=MY_VERIFICATION_CODE
Request https://graph.facebook.com/oauth/access_token?client_id=MY_API_KEY& redirect_uri=http://www.facebook.com/connect/login_success.html& client_secret=MY_APP_SECRET&code=MY_VERIFICATION_CODE
Facebook will respond with access_token=MY_ACCESS_TOKEN
I think that i may be looking at the wrong instructions and this is for a facebook connect or anything else besides an actual facebook application inside apps.facebook.com/app_name.
I would really appreciate any relevant information regarding the issue. I'm simply trying to create a simple facebook application that prints the name of the user.
In general after I fetch the acces token of the user i can do the following:
FacebookClient facebookClient = new DefaultFacebookClient(MY_ACCESS_TOKEN);
User user = facebookClient.fetchObject("me", User.class);
out.println("User name: " + user.getName());
My problem is how do i properly fetch the access token of the user? in the information i showed at the top of the post, it shows that i need to make 2 requests. the first for the code and the other for the acess token. and the request for the access token actually reveals my app secret key to the user because each time i forward him to a different page the user can easily view the get and set parameters.
so i guess i'm pretty lost here.
please help! :)
thanks
update after comments
with these instructions i need two times to redirect the user's page. first to get the code and then to get the access token. the user can see these two redirections and because of that he can easily see the facebook application key and secret key from the get parameters. how do i make sure that these steps are hidden from the user?
As stated in the comments, these are the steps you need to take to access Facebook's graph API. However, to answer your second question:
"How do I make sure that these steps
are hidden from the user?"
Only the first request should be performed by the user's browser. The purpose being that Facebook wants to make sure it is the sole authorization provide for the user's Facebook identity. Depending on the application you are writing, you would either use the redirect URL to point to the default redirect URL that you specified, or specify a custom url on your website that you will use to retrieve the token. The first approach is typically used by stand-alone applications such as mobile devices that can control how the browser handles redirects. The second approach would be used for a custom web-based application. Once you receive the access token, then you would perform the second operation within your code (using your favorite http apis) and not through the browser. The redirect on the access_token url is compared against the redirect url specified on the authentication-url. Facebook uses it for validation only and does not perform an actual redirect on the successful completion of the request.
Here are the high-level steps:
Redirect user's browser to the authentication-url specifying the appropriate redirect_uri
Retrieve verification token from redirected browser request
Perform access_token retrieval using your preferred HTTP framework (no user input required)
Parse results and retrieve access token
Initial restfb with token and use as needed
The REST API has been deprecated. You should look in to the JavaScript and Graph APIs instead - there is a good article on this here: http://ocpsoft.org/opensource/creating-a-facebook-app-setup-and-tool-installation/ (Three part series, very detailed :)

Categories