Currently, I use the following flow to access the OneDrive of a user that is logged in:
Log in the user as follows:
Force user to login using the windowslive social connection using connection=windowslive.
Supply required downstream scopes using connectionscope=xxx
When the user is logged in, I use the Auth0 management API on the backend to fetch /api/v2/users.
This yield information about the user. The identities field contains an entry for the windowslive. connection. one of the fields is access_token, which I can use to access the graph API with the scopes provided earlier. Brilliant!
However, now I want to be able to access the API from the backend without user interaction. When adding the access_offline scope to the connection scopes, a refresh token appears in the identity object. This means that the offline access has been granted. However, at this point I am stuck. I can use the access token provided for me but at some point, this access token expires. Now I need to refresh it and I have no way to go about it.
How do I use this refresh token? Do I need to use the Auth0 api for this?
Why doesn’t Auth0 handle refreshing the access token automatically? It seems it has all the information required to do this.
To use the refresh token to get a new access token, you must make a refresh_token grant request with your refresh_token in the request. It would look something like the following:
For convenience, Auth0 typically stores any Access Token that might returned by an upstream IdP as part of first-factor authentication. And Auth0 typically stores such a token as part of the user’s profile record in the corresponding entry in the identities array; accessible via a call to the Auth0 Management API (as discussed). However, such tokens are typically short-lived, and typically are provided so that Auth0 Extensibility - such as an Action, Rule or Hook - can call upstream IdP services - i.e. 3rd party APIs - to obtain additional information about a user as part of the login process. Auth0 does not typically store any Refresh Token that may be delivered by an upstream IdP, nor does it automatically refresh any stored Access Token delivered by the upstream IdP “behind the scenes” as it were.
For anyone looking to obtain a specific Access Token in order to call some 3rd party API from their application (e.g. a Google API, OneDrive API, Facebook Graph API, etc) - either directly, or via an SDK - then the recommendation would typically be to perform some redirect in the application to the 3rd party Authorization server directly. This can do this once authentication via Auth0 has completed, and it should be a seamless operation - i.e. the user should not be asked to interactively login - as the (3rd party) SSO session already established by authenticating via Auth0 will typically be used.
Building a solution that relies solely on using the 3rd party tokens Auth0 keeps will likely be problematic, as when the token expires there is no option but to go back to the 3rd party Authorization Server because Auth0 has no way of renewing any existing - or even obtaining a new instances of - the token for calling the 3rd party APIs.
Thank you @rueben.tiow and @peter.fernandez for your responses. I see what you both are saying but it seems like there’s a bit of contradiction here.
Rueben you’re saying that the access_token for the IdP will be refreshed in the identities array but it sound like Peter’s saying that the access token will not be refreshed automatically. @peter.fernandez does this mean if we use the recommended solution, we will get an updated access_token for the IdP?
Using an Auth0 Refresh Token will refresh an Access Token generated by Auth0, yes. However, it will not refresh an Access Token delivered by any upstream IdP (i.e. the one stored in the identities array).
I want to access the resource offline from the backend, which means I can’t redirect (since user intervention is not an option). Does this mean I will need to access the 3rd party authorization server directly? How would I do that? I hoped that using Auth0 would hide this complexity from me.
So you can still use a Refresh Token if the upstream IdP supports it. It’s just not an Auth0 issued Refresh Token. What would typically happen is that once Auth0 execution completes and the Auth0 application callback is driven - i.e. the callback defined by the redirect_uri - the application would then redirect to the 3rd party auth server to obtain the 3rd party access token and (optional) refresh token. This redirect will typically be done in the Auth0 callback. 3rd party SDKs - such as the googleapis SDK for node (googleapis - npm), for example - will typically then use the tokens acquired via the 3rd party authorization server to allow calls to the (3rd party) APIs - often seamlessly refreshing any access token where required.
For my understanding: What would happen with the token that was previously issued by Auth0? Would it be overwritten? Would both tokens live together? Most examples and documentation I’ve worked with seem to assume that there only is a single token present (but I’m more than willing to admit my understanding is far from perfect at this point ;)).
No problem; this stuff can get more than a little complicated!
So Auth0 issued access tokens are designed for use by first-party APIs - i.e. the APIs you build yourself. They are completely separate from any tokens required for accessing third-party APIs (such as the OneDrive APIs built by Microsoft). Most of the documentation you will see regarding Auth0 examples, et al, will simply talk about the set of tokens Auth0 issues: namely access tokens for first-party APIs, and the id tokens issued to first-party applications (as in those applications you build yourself). Auth0 does not issue tokens on behalf of anyone else.
What Auth0 can do is provide access to any third-party access tokens generated as part of them (said third-party) also acting as an Identity Provider - e.g. windowslive acting as the identity provider in your case. However these third-party tokens really shouldn’t be used outside of an Auth0 extensibility context, as there a numerous caveats.
Because third-party access tokens are totally separate from Auth0 (first-party) access tokens, renewing them with a call to the third-party authorization server won’t affect the ones generated by Auth0. It may however affect the (third-party) ones stored by Auth0. And that really depends on the implementation details of the third party authorization server - in essence whatever its token refresh policy is and how it handles that . In general, access tokens themselves are typically designed to be short lived anyway, so will naturally expire - regardless if they’re generated by Auth0 or some third-party.
I do get that I can’t directly use the token provided by Auth0 to access a 3rd party API. However, I had been (ab)using the access token provided by the Auth0 user API as it was both convenient and extensible across many providers. From our use case, this would be a big advantage as we wouldn’t have to deal with the details of each IdP individually. Now I understand that we’ll have to redirect to the IdP to get a current access token which we can use to access the 3rd party API.
Are you aware of any documentation and/or code examples on how to do this (e.g. multi-step authentication against multiple providers) in ASP.net core? Is there a name commonly used for this pattern? I have a hard time finding the right documentation to get me underway.
So it sounds like you have quite an interesting use case, where you’ve identified how leveraging Auth0 to front multiple third-party IdP’s can abstract away the need to know the specifics of each third-party Authorization Server when it comes to obtaining tokens to call the APIs each third-party provides. Right? Interesting. Can you share some other situations in addition to windows live and the OneDrive APIs you mention? Feel free to DM me if you’d prefer
I’d agree, there is significant merit in using Auth0 to do what you’re proposing The problem is that with out due care and attention (in situations like this we normally recommend engaging with Auth0 Professional Services) it’s all too easy to create a vulnerable attack surface. However, going back over the details in this thread it does sounds like you’ve understood the ramifications of using Auth0 stored third party tokens outside of Auth0 extensibility - only using them in an APS.net core secure back-end context, for instance, being a good example. So as long as you follow the few basic principles below (listed in no particular order) you should be in good shape; I would definitely recommend engaging with Auth0 Professional Services to review your design patterns in more detail though just to be doubly sure:
Don’t acquire third-party tokens from an insecure context. And don’t transfer them to an insecure context either. Auth0 originally obtained such tokens via a secure - i.e. regular web application back-end workflow using a Client Secret - so sharing them with a less secure context could have some very serious security implications. See here for more details.
Do request a third-party Refresh Token. Access tokens should, ideally, be short lived. By design, short lived access tokens are inherently more secure as they limit the potential attack surface and therefore reduce the potential a bad actor has to perpetrate an attack. So whilst you can securely read a 3rd party access token from Auth0, it will eventually expire! And probably sooner rather than later!
Store the third-party Refresh Token securely; don’t rely on the Auth0 stored token more than once. Refresh Tokens can come in a variety of forms, and you can read more about that in the blog post here. Because you don’t know necessarily know what form is being delivered by a third party, you may not be able to use the Auth0 stored one more than once.
Refresh the third-party Access Token using the third-party Authorization Server directly. And don’t forget to securely store any Refresh Token returned, using it to refresh any third-party Access Token in the future. The previously linked blog post should explain about this from a Rotating Refresh Token perspective, and the link here will explain why Auth0 doesn’t refresh third-party tokens automatically.
I’d also recommend making use of the connection_scope parameter if you’re not doing so already. Rather than setting explicit scopes on the Auth0 Connection definition. The former is more in keeping with the Principle of Least Privilege, whereas the latter will apply to all Auth0 Applications and all Users who use that connection.
As described in our documentation (here) the process for engaging with a third-party Authorization Server varies. So sadly we don’t provide code examples or the like for doing this. Third parties often build SDKs that can help - the googleapis SDK for Node.js being a good example of one which takes care of automatically refreshing any tokens too. However, if you just have to engage for token refresh, then it typically will be a whole lot easier as you will typically just need to call the equivalent /token endpoint as opposed to doing the whole /authorize dance too