I'm developing an SPA with Azure AD B2C as the identity provider. I'm using the MSAL JavaScript library and it's mostly working fine. I can create users, log in and get access tokens for my Web API back-end.
The only issue at the moment is that the B2C endpoint is not returning refresh tokens so when the access token expires, the acquireTokenSilent method in the UserAgentApplication class, which is meant to refresh expired access tokens using the refresh token, fails.
My application in B2C is configured with "Include web app / web API" and "Allow implicit flow" set to "Yes" in its Properties. In the API Access section, both the "openid" and "offline_access" scopes are ticked under "Access the user's profile". The application itself has "read", "write" and "user_impersonation" scopes (not sure if that matters).
"offline_access" is included in my scopes and I event tried creating an application one, like the read/write scopes and include that as well (as "https://mytenant.onmicrosoft.com/testapp/offline_access") but nothing seems to work. The responses never have a refresh token, neither for the id token not for the access token.
What I have noticed is that when I go to the SignUp-SignIn policy I created and try to run the endpoint from there, the "offline_access" scope isn't even available in the drop-down. Even if I copy the "run endpoint" link at the bottom and add the scope to the URL before running it, the response doesn't include a refresh token.
When I click on the link at the top, it seems to give me some details about the endpoint and only "openid" is under the supported scopes.
Not sure what I'm missing here so any ideas would be appreciated.
The Run Now link generates an auth request that uses the implicit flow to log in. Implicit flows, by definition, do not allow you to obtain a refresh token due to security reasons. Therefore, the drop down does not give you the offline_access scope since it won't work. If you want a refresh token, you need to run through the confidential code flow. If you choose to, you can do this by manually modifying the URL that the "Run now" link generates. Specifically, in the URL:
Set response_type=code (not token)
Add "offline_access" to the list of scopes
Once you obtain a code, make a POST request as shown in the documentation to exchange the code for a refresh token.
Related
I have a back-end processor, (imagine a chron job once a day generating reports), that needs to integrate with a third-party system. Their APIs only support the "Authorization code" grant type. The problem is I can't even fill out a request for a token as I don't have a redirect_uri (no website), and I definitely don't have a user of any kind. I'll just have the OAuth clientId and secret I provisioned via their developer portal, (Mashery), for my back-end report processor app.
I want to use the "Client credentials" grant type/flow since I'm just a back-end service.
Is there any way to fake this or hack it so my little back-end service can somehow work with authorization code flow?
Thanks in advance
No, there is no way to hack it. Client credentials only authenticate the client. A token issued for client credentials have no information about the user. If their API needs information about the user (you probably get information only about your user), then you need to have a token issued with Code Flow.
What you can do is to generate the OAuth token yourself. E.g. you can use oauth.tools to perform a Code Flow with their Authorization Server, or you can perform the flow from browser with a dummy redirect URI (e.g. http://localhost), the get the code returned from authorization request and perform a token request from curl.
Once you have an access and refresh token you can hard code them in your script (or read them from an env variable or file, etc). You can then call the API as long as the access token is valid, and use refresh token to get a new access token when it expires. You will not have to perform a new Code Flow for as long as the refresh token is valid.
Is the authorization code grant type only for interactive accounts? I'm working with an API that does not appear to support client credentials grant and unless I fallback to basic auth (user:token) I do not know how we would make this work for a user that (to us) is a service account.
The piece I am struggling with is the return of the authorization code. If I hit the generated URL to request the auth code I receive a dialog asking me to allow/validate access and by accepting I am returned to the redirect_uri with the code param. This required human interaction which in our scenario we would not have. Auth codes are not supposed to be long lived so I cannot just save this for future use.
The first piece, getting an authorization code, needs to be done manually by a human.
The authorization code is short-lived so you wouldn't want to store the auth code for use later.
Thankfully, you can trade in that authorization code for an access token and refresh token. Though the access token expires, usually around an hour, the refresh token often remains active for an extended amount of time (this is can vary by API). The API I am working with at the moment does not document when it expires, it may not expire ever.
We'll just note that if the refresh code ever fails/expires then we should manually go to the authorization URL to get a new auth code which we can trade in for a new access token and refresh token. We'll keep the refresh token stored securely and will plug in the refresh token in our automation. The automation will not make authorization_code grant type calls (that part we'll still keep manual) and will only make refresh_token grant type calls (those can be automated) as well as the calls to do the actual work with the API once we have a fresh, valid access token.
I can't figure out the difference between Token and Grant in Doorkeeper. In which moment, Doorkeeper creates an Access Grant and when an Access Token? The documentation doesn't seems to say nothing about it and now I'm reading the code but is not a dozen lines.
I recommend to also read the documentation of oauth2
As I understand, Doorkeeper is based on the protocol described in that documentation too.
In doorkeeper, you will get access grant first and then access token.
Access grant usually only lives very short (the default in doorkeeper is 10 minutes).
You will get this by requesting GET to api-url/oauth/authorize (don't forget to put client_id, redirect_uri, and response_type as parameter. response_type will have value "code").
Once user allow the apps (user clicks "allow" button), doorkeeper will return the access grant as parameter in the returning url.
Get that code and you can now use it to make POST request to api-url/oauth/token to get your access_token and refresh_token.
Using access_token, you can get the resources of the API in a limited time (Doorkeeper's default is one hour if I'm not mistaken).
When acces_tooken expired, use refresh_token to get new access_token and so on.
In summary, access grant is the key that given as the sign that user has allowed the apps to use its resources.
Access token is the key that is given to permit an apps to use resources in a limited time which has defined.
Hope it can help.
I'm assuming you're talking about the Web Server flow, as you're using a Ruby gem in a Rails app (as you know, there are 4 flows).
Usually in the Web Server flow, Grant is the moment when the user clicks in a link to consent authorization: he/she will be asked to authorize the app to read/write data.
If consent is granted, then the app will get a temp code. With this code, in the background, the app will ask the Token for the service provider.
Then, only with the Token, the app will be able to use the service provider APIs.
A while back, I registered an application as an OAuth client using the steps described here: http://www-10.lotus.com/ldd/appdevwiki.nsf/dx/Getting_Started_with_IBM_Connections_API_via_OAuth. When using the application to run through the OAuth procedure to get the refresh token and access token, everything works out and a new refresh token and access token are granted. When going to the Application Access page after the whole OAuth process, the application does not show up within the user's Application Access page. Even now, after a few days of not going through the OAuth process, the refresh token can still be used to get a new access token and this in turn can be used to access the user's data. What I want to know is why would this occur? Did I miss some steps in the whole process or am I just not understanding the functionality of the Application Access page?
You will want to read up on the various oAuth settings that are possible with IBM Connections.
http://www-01.ibm.com/support/knowledgecenter/SSYGQH_5.0.0/admin/admin/t_inst_installingandenablingoauthtai.dita
In particular you'll want to look at
oauth20.issue.refresh.token true If set to true, clients will
receive a refresh token. If set to false, clients must request
authorization when the access token expires.
it means you should check your WebSphere Console and check the Trusted Authentication Interceptor settings and see if that is set to True or False.
there's two ways to fetch access token.
use authorization code to exchange it
use refresh token to refresh it
think about it!!
though the word of exchange and refresh is different,what they do are the same.
both action need to parse client id & client secret(Or signature) and token
we can just save the authorization code in our system,and again use auth code to
refresh access token just like refresh token do.
Except that authorization code is expired too soon.
so I wonder
why the designers of oauth2 designed these two concepts while not used just one single concept or say just design the authorization code and give it a long expired-time.
I am afraid that you have not understood the concepts of oauth2 too well. There aren't just two ways of getting the access token, there are more. Each is basically called a 'grant type'. I'm describing the use cases of the ones which I have deployed below :
1- Authorization code :
This is similar to the flow of "Login with Facebook" etc buttons which you see on different websites, which allow you to register/login using your facebook etc accounts. Here, on clicking this button, control is directed to Facebook, where the user enters his login credentials. If successful, an authorization code is sent to whatever redirecturl you entered while registering as a developer with Facebook. You then use this authorization code to request the access token service to get the access token which you then use whenever accessing any Facebook webservices to get the user's details.
2- Client credentials :
If you are running your own webservices and you want to allow access only to valid clients, then this is the grant type you would use. For example, you are running your webservices and now you want to consume it in your own native mobile app which you distribute through any app store. This will ensure that only those who installed your app will be able to access your webservice.
3- User credentials :
Same as above, only in this case this would allow you to authenticate a registered user as well and then give access to user restricted services like my account etc.
4- Refresh token :
By design, the access token service gives an access token as well as a refresh token. You would use the refresh token obtained from it here to refresh an expired access token. Essentially, this does not generate a new access token, it only "refreshes" an existing token. It will give you a new access token and refresh token and extend the expiry time. When this access token expires, you again call refresh token using the refresh token obtained last time, and keep repeating the process every time the token expires.
According to RFC 6749 10.5 The authorization codes are short lived and single-use. Therefore, you cannot use them again and again to get new authorization tokens.
Authorization codes MUST be short lived and single-use. If the
authorization server observes multiple attempts to exchange an
authorization code for an access token, the authorization server
SHOULD attempt to revoke all access tokens already granted based on
the compromised authorization code.
There are some additional misconceptions that seem to be presented here, so I wanted to help clear them up.
The differences between an access token and a refresh token can be summarised as follows:
An access token is used to provide access to restricted resources to an authorized client after authentication has taken place.
A refresh token, on the other hand, is used by a client in order to retrieve new access tokens with identical or narrower scopes.
The different between the Authorization Code Grant and the Implicit Grant (as well as their usages) help to illustrate how both should be used.
In general, the Authorization Code Grant should be preferred over the Implicit Grant unless a resource is being accessed directly via a publicly implemented client (e.g., browser-run code) or there is a specific reason that the Authorization Code Grant cannot be used (e.g., feasibility or performance). This is explained in the RFC definition for the Implicit flow.
During an Implicit Grant, access tokens are exposed to the user-agent which could lead to them being compromised since they are no longer under the control of a server app (confidential client) that could otherwise be requesting the protected resources. This is why refresh tokens are not issued during Implicit Grants. Though access tokens might be exposed, they are short-lived. Resource tokens, on the other hand, are long-lived and can be used to retrieve new access tokens.
The Authorization Code Grant, on the other hand, prevents the potential for refresh tokens to be exposed. During this grant, the authorisation server issues a code instead of tokens. The code is then passed by the user-agent to the client application which exchanges the code with the authorization server to retrieve access and refresh tokens. Since the code exchange is performed directly between the client application and a trusted authorization server, a refresh token can be securely issued.
The RFC spec cautions that the security implications of implementing the Authorization Code Grant in a public client versus a confidential (e.g., server-side) client should be seriously considered. "More OAuth 2.0 Surprises: The Refresh Token" clears up a few misconceptions and furthers the idea that auth codes should not be sent directly by the user-agent to the auth server in order to retrieve refresh tokens, though the OAuth 2.0 spec does not technically dictate this.
Answer from #ComfortableDust has the answer to original question. Just quoting the exact text from his reply
The Authorization Code Grant, on the other hand, prevents the potential for refresh tokens to be exposed. During this grant, the authorisation server issues a code instead of tokens. The code is then passed by the user-agent to the client application which exchanges the code with the authorization server to retrieve access and refresh tokens. Since the code exchange is performed directly between the client application and a trusted authorization server, a refresh token can be securely issued.