For many collections in Postman we use authorization with the grant type=Authorization code (to Azure). For requests using the grant type client credentials I'm able to write the prerequest script which acquires the token automatically (if needed) and I would like to have such a script for the authorization code flow too. There are many examples related to basic authorization (user name/password) flow out there, but I haven't found any for the authorization code flow.
Here are the steps I have to do according the MS docs):
I call POST method to the https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize with all required parameters, as redirect_uri I use https://www.getpostman.com/oauth2/callback
After successful authentication Azure sends the code as url parameter in the callback request to provided redirect_uri. In the browser it looks like this https://www.getpostman.com/oauth2/callback/?code=authorizationCodeGeneratedByAzure
To proceed further I would need now to somehow observe the redirect_uri, to catch the incoming request (the callback from Azure) and somehow grab the code from the request url parameters for further usage in the following request for the token acquisition. And this is what I can't figure out how to do.
So my question is:
How can I get the authorization_code from the url of Azure authentication response sent to redirect_uri after the successful authentication in the Prerequest script?
Hope you are doing it in the authorization_code flow and application as WebApp.
So, for authorization_code flow there are 2 steps to get the access token.
To get the code first from the /authorize end point.
Use that code to get the access token from /token end point.
https://www.getpostman.com/oauth2/callback/?code=authorizationCodeGeneratedByAzure
As you mentioned that you got the code from redirect-uri, you just need to extract this code to pass in token end point along with the client_secret to get the token.
After successful authentication Azure sends the code as url parameter in the callback request to provided redirect_uri.
For further process use that code along with the client_secret for the token acquisition.
Below is the sample view from the Postman.
Related
So right now I'm implementing oauth2 in my server, but I just want to support the client_credentials grant. The thing is, the node-oauth2-server says that supports this type of grant, and I pretty much debugged the whole library, and there are some things that doesn't make sense to me.
As far as I understand, the client_credentials grant should work like this:
An internal request should be made to generate the client_id and client_secret for the client, this is the only time we will get the client_secret and we should give this to our client
The client_id should be stored in database with any extra data (like the account id associated or something like this) and a hash of client_secret so we can later validate it
The client sends a request to the server including the client_id and client_secret
The server should then generate an access token (in my case I will be using JWT) and return from the request. We also need to store this token in database so we can revoke the permission if needed
The client must use this access token in future requests to access resources from server, and the server will validate on each request if the token is valid (didn't expire, didn't lose permissions, etc)
I may be wrong about this, but this is what I need and this exactly what C# Identity does and it is explained here.
In my case I'm working with nodejs. Actually is a NestJS project, so I was trying to use this lib which is basically a wrapper for node-oauth2-server, and if you take a look inside node-oauth2-server, looks like they only support authorization codes, this is because the AuthorizeHandler.handle() always returns an authorization code and AuthenticateHandler.handle() always expects the authorization code and returns the access token. Basically I need to call the AuthenticateHandler.handle() but instead of checking the authorization code, I must pass and check the client_id and client_secret.
This is a recent issue which has the exact same issue than me: https://github.com/oauthjs/node-oauth2-server/issues/552
So, first, I want to confirm that I'm right and this lib have this implemented in a bad way, and second, is there any other nodejs lib that has client_credentials built in?
As you've mentioned that it doesn't support client_credentials grant at the moment, you can still utilize the authorization code flow grant type internally to get the access token.
Prepare client_credentials grant type request and submit to server.
Map this request to authorization code flow with additional
attributes require for the authorization code flow.
Submit the request to Authorization server.
Get the code from response.
Prepare the token exchange call with the oauth code.
Get the access_token.
Return the token in response to client_credentials call.
For background, see: this question
So, the first step in the Authorization Flow is to get the authorization token using a URL in the web browser like this. For a desktop app it needs to have the following signature (I un-encoded it to make it more readable):
https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize
?client_id={client id}
&response_type=code
&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient
&response_mode=query
&scope=openid offline_access https://graph.microsoft.com/.default
This ends up at the specified redirectURL (assuming I set the same redirectUrl in the Application registration in Azure and authenticated. All good. The response looks something like this:
https://login.microsoftonline.com/common/oauth2/nativeclient?code=OAQABAAIAAAA...ggAA
That code is then used to generate an access_token and a refresh_token using a POST http request from my VBA (MS-Access)
https://login.microsoftonline.com/{tenant Id}/oauth2/v2.0/token
grant_type=authorization_code
client_id={client id}
scope=https://graph.microsoft.com/.default
redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient
code=OAQABAAIAAAA...ggAA <== ie the code that was copied from the URL in the Authorization step above
That call returns both an access_token (expires in 1 hour) and a refresh_token (default expiry in 90 days). The refresh_token is used to get another access_token after it expires.
So far, so good.
The first step (get the Authorizaion Code) is run in a browser and the resulting code is copy-pasted into my App to be used in the second step (to get the access_token). Each time the access_token expires, the refresh_token is used to acquire another access_token AND another refresh_token, giving another 90 days. That all works fine.
My question is this:
After 90 days of inactivity both the access_token and the most recent refresh_token will have expired. Is it the case that I will then need to return to the first step, get a new Authorization Code via a browser window, copy and paste the code from the web browser url and use it for the second step?
Is it the case that I will always need to use a web browser to get an Authorization Code or is there some programatic way to do that which I have completely missed?
Thanks.
Murray
Is it the case that I will then need to return to the first step, get
a new Authorization Code via a browser window, copy and paste the code
from the web browser url and use it for the second step?
Yes, you are right.
is there some programatic way to do that which I have completely
missed?
Yes, resource owner password credential (ROPC) grant flow allows an application to sign in the user by directly handling their password. The ROPC flow requires a high degree of trust and user exposure and you should only use this flow when other, more secure, flows can't be used.
I tried to login with two separate website, both using "login with Google". Intercepted the auth code from the 1st site, and exchange it with the auto code to the 2nd site. Neither site will let me login. I remember in RFC6749 it is not specified that the auth code to be bound with any identity, is it implemented so to increase security?
This is indeed part of OAuth2.0 security:
Exchange the Authorization Code for an Access Token
We’re about ready to wrap up the flow. Now that the application has
the authorization code, it can use that to get an access token.
The application makes a POST request to the service’s token endpoint
with the following parameters:
grant_type=authorization_code - This tells the token endpoint that the
application is using the Authorization Code grant type.
code - The
application includes the authorization code it was given in the
redirect.
redirect_uri - The same redirect URI that was used when
requesting the code. Some APIs don’t require this parameter, so you’ll
need to double check the documentation of the particular API you’re
accessing.
client_id - The application’s client ID.
client_secret -
The application’s client secret. This ensures that the request to get
the access token is made only from the application, and not from a
potential attacker that may have intercepted the authorization code.
from https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type#exchange-the-authorization-code-for-an-access-token
Short answer : Authorization code is bound to the client it was issued
This is strictly enforced by the RFC6749 and stated in 4.1.3. Access Token Request section. Also, it is one of many checkes authorization server perform to validate a token request. Specification has following stated,
The authorization server MUST:
o ensure that the authorization code was issued to the authenticated
confidential client, or if the client is public, ensure that the code
was issued to "client_id" in the request
So when authorization server will cross check authorization code against client id or client credentials depending on client type.
Furthermore, authorization code is a temporary secret which must not be exposed to other parties. This is highlighted in security consideration's 10.5. Authorization Codes section.
I'm using developer sandbox to make all my api calls.
It's website build with laravel 5.2
All api calls are made with guzzle/guzzle.
I'm trying automate sending pdf contracts (creating envelopes) using docusign api.
I followed steps from Using the Authorization Code Grant
I had no problem with:
Starting the Authentication Code Grant
Handling the Response
Exchanging the Code for a Token
Getting the User’s Account and Base URI Information
After I get userinfo, there is only one account, so I used that accounts base_uri for all subsequent api calls
{base_uri} + "/restapi/v2/accounts/" + {account_id}
In all my subsequent api calls I'm also adding header
Authorization: Bearer eyJ0eX...MrhIddzBAQ
where I'm using access_token that I've got in step Exchanging the Code for a Token
When doing a create envelope api call, or any other api call, using access_token, base_uri and account_id I get
POST https://demo.docusign.net/restapi/v2/accounts/<account_id>/envelopes resulted in a 401 Unauthorized response
What I tried
Test using the access_token in docusign API explorer:
I went to API EXPLORER - create envelope
I used Authenticate using Sandbox Account to authenticate with the access_token that I've got in previous calls to docusign. Same for the account_id.
When I click on SEND REQUEST, I get 401 Unauthorized response again.
When I use Authenticate using Sandbox Account, but this time I click on Get OAuth2 token (that generates new token), and I click on SEND REQUEST, I get success message.
Then I copied this access_token (from Request) into my website to test the api call, and this time it worked. It also worked for all other api calls that I was making to docusign.
So, using access_token that I get after Exchanging the Code for a Token, I get 401 Unauthorized for api calls
When I use access_token that I generated in API explorer, all api calls to docusign work in my website.
What I also tried
Use refresh_token to get new access_token. Still 401
Xdebug, going step by step to make sure that all params/headers are set before api call. They are, and they are the same as api explorer.
Guzzle option debug => true to get more information about the request, and to compare with what's sent in API EXPLORER, and they are basically the same, except the tokens.
Postman to make request to api, (just to eliminate any chance that I have errors in my code), with same behavior:
401 with token that I get from docusign
success when using API EXPLORER generated token
I'm kinda lost on what to do next and how to solve this, I'm sure it's something simple, but I can't seem to locate the problem.
Update
I used Larry K's answer and found that my problem was with the scope value in /oauth/auth call. I changed it to scope=signature%20extended, and everything works perfectly!
When you click the Get OAuth2 token in the API explorer, you are going through the complete Authorization Code Grant flow, including the new token.
Since this works, but the token your app obtained via the OAuth Authorization Code flow doesn't work, this tells me that your app has an issue.
Check:
Logout from DocuSign. Login from your app. Are you transferred to DocuSign to log in correctly? And then redirected to your app?
Are you requesting the "signature" scope in your request? Check spelling and capitalization of the scope name!
When you're redirected to your app, your app receives the authorization code as a query parameter. Do you get it ok?
When you convert your authorization code to a bearer token are you storing the complete bearer token? It is quite long.
When you send your Envelopes::create request, are you including a space between the word Bearer and the token itself?
Are you making your API call to demo.docusign.net (not .com)
If the above doesn't help, then please update your question (you can edit your question itself) with a trace of your request.
Hi I am working with Open Id Connect protocol for authentication scheme. I just want to know what is the exact difference between basic client and implicit client scenario's in Open Id Connect.
The difference is that basic client uses OAuth2 Authorization code flow, while Implicit client uses OAuth2 implicit flow.
You can find the differences between these two flow in OAuth2 RFC (https://www.rfc-editor.org/rfc/rfc6749), but basically:
Authorization code flow is composed by two requests and responses. The first request (response_type=code) asks for a authorization code. The provider responses (if authorizated) with a authorization code. Then a second request is made (response_type=token) sending this code and asking for the access token. This flow is used from server-side.
Implicit flow is composed by one request and response. The request (reponse_type=token) asks directly for the access token, and the response injects the access token into the redirection URL. This flow is used form client-side (script).
Hope this help!