Multiple resources in a single authorization request - azure

We currently use the following authorize url:
https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2Foutlook.office365.com
We want to also use the Graph API, so I added the following:
https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2Foutlook.office365.com%2F%26https%3A%2F%2Fgraph.microsoft.com
I've tried different delimiters between the two resources, but couldn't get it to work. Each one resource works separately. I hope that more than 1 resource at a time is supported?

I think what you're trying to do here by passing multiple values to resource parameter directly will not work (probably not a supported scenario, but I'll wait till someone from Microsoft confirms or I find Azure AD documentation stating exactly that. In the meanwhile, here's an old blog post that says something like this, but it's a blog talking about SSO and old from 2014 :), so don't want to rely solely on this.)
Below I'm explaining how you can make this scenario work by reusing refresh tokens and without passing both resource ids in same call.
(NOTE: This approach will work for Authorization Code Grant Flow but not for Implicit grant flow like a JavaScript based SPA, because no refresh token is returned in that case)
Once the authorization code is available from authorize endpoint, you go to Azure AD token endpoint requesting token for a single resource (using REST call to endpoint or something like ADAL library AcquireToken method depending on your application requirements)
You get back an access token + refresh token as a response to your call to token endpoint. The access token is valid for resource that was mentioned in first call (say graph.microsoft.com)
Then using refresh token you just got, you make another call to token endpoint (REST or ADAL AcquireTokenSilent so that there isn't a popup to ask for user credentials this second time) and get a token for the second resource by specifying the 2nd resource id in case of this call
The access token you get this time is valid for the 2nd resource.
In fact you can continue doing this and hence the name Multi-resource refresh tokens shows up in some places. Although now all refresh tokens are supposed to be multi-resource or valid to be used for requesting any resource that your application has consent for.
Links that can help you in understanding further and implementation
Call Multiple Services With One Login Prompt Using ADAL
Refresh Tokens for Multiple Resources
This SO Post.. look at comments as well.
This SO Post

Related

Azure B2C implicit flow: acquire new access token witout the use of an iFrame

In the Azure B2C documentation you have this information about silently acquiring new access tokens when the previous one expired.
ID tokens and access tokens both expire after a short period of time.
Your app must be prepared to refresh these tokens periodically. To
refresh either type of token, perform the same hidden iframe request
we used in an earlier example, by using the prompt=none parameter to
control Azure AD steps. To receive a new id_token value, be sure to
use response_type=id_token and scope=openid, and a nonce parameter.
Is there a way to do this without an iFrame?
You can do it with a full redirect by calling acquireTokenReditect() with MSAL. There is no other option in a javascript app. This of course is not going to be a good UX as you’d need to do it every time the api resource changes or scope changes.

Does the retrieved OAuth2.0 authorization code for Azure AD web applications expire?

In order to access resources in Azure AD web applications we retrieve an authorization code using the following workflow:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Now my questions is, does this retrieved code also have a specific lifetime (like tokens have) or will it never expire? I guess it won't expire but I need to be sure about that.
Yes, the authorization code has a lifetime of 10 minutes I think.
You use it to get the tokens you need and then throw it away.
You'll get refresh tokens so you can use them to get more tokens later.
ADAL.NET for example handles the token refresh for you, assuming you properly implement a token cache.
Reference: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-id-and-access-tokens (scroll all the way down) (it's for the v2.0 endpoint, but codes are similarly short-lived in v1)
Authorization codes (work or school accounts)
10 minutes
Authorization codes are purposely short-lived, and should be immediately redeemed for access tokens and refresh tokens when the tokens are received.

Microsoft Graph API: how to get access token without browser

I would like to upload a given file to Sharepoint. I'm using the Microsoft Graph API.
The documentation follows this workflow:
1. If no token, redirect the user to the Microsoft signin page.
2. The user is then redirected to the application, with an access token
3. Use access token to have an authorization bearer
4. Do what you gotta do...
My problem is the sign-in part. I don't want my users to be redirected to the Microsoft signin page. I want my application to connect and get the access token in the background (with cURL or whatever).
How can I do that? Why is the "open in browser" necessary?
I tried to replicate the sign-in process, but all I get back is the HTML response from the signin page.
Thanks in advance.
Your application act as a single-tenant service or daemon app.
The documentation about this scenario is here : https://developer.microsoft.com/en-us/graph/docs/authorization/app_only
The application must be registered in the AzureAD directory corresponding to the Office365 tenant
A first request is made by passing the application unique identifier and secret key as registered in the directory. This request returns an access token
The access token can now be used in the Authorization header of the following request to the Microsoft Graph API.
This method (of using Client ID and Secret) works well but there are other ways which may be better suited for similar scenarios.
The one major thing which is missing in access token generated this way is a user, meaning the token only contains the identity of the OAuth application (client) which called it but is not associated with any user for the request.
This could have a couple of implications:
Since the token is not associated with a specific user you will not know who performed the operation. In your example, you would not know who uploaded the file (and other similar information may be missing).
Access token without users will not work at all for some methods. For those, you need a delegated token.
Creating a delegated token requires some effort, if you are interested you can find the details in my article:
Getting Access Token for Microsoft Graph Using OAuth REST API

Spotify: Permanent auth with authorization code workflow

i am building a prototype to prove deriving user playlist etc. from Spotify.
As this is user information, i've to use Spotify's authorization code workflow (refer https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow)
In this workflow, an application requests user to grant scoped privileges so relevant information can be pulled out.
In the series of calls that follow:
call to /authorize
calls back a redirect_uri sent in request and sends in a code
e.g.
redirect_uri=../abc receives ../abc/callback?code=xyz
as is exemplified in docs.
xyz is then sent over to /api/token to get access_token and refresh_token
Is there any way one can avoid to repeatedly invoke /authorize after once the grant has been given by user?
In-effect, can i not treat the code (from /authorize) like an oauth token and preserve it (say in database) to get a new access_token every time i need one? (as a direct comparison check facebook's oauth token that can be saved and reused to authenticate every next time)
How can i remember a user has already granted me access to his/her Spotify profile and data?
Please indicate if i am missing something obvious from documentation. please point me right if this has been specified elsewhere.
many thanks!
For this use case you can use the Authorization Code flow. What you should persist is the refresh_token it returns, which can be used to obtain access tokens. You can also optionally persist the access token, that you can use during one hour, so you don't need to obtain a new access token every time.
There is a FAQ in the Authorization Guide that talks about a similar scenario, where a user would want to manage her playlists without having to go through the login process every time:
You basically need an access token and a refresh token issued for your user account. For obtaining a pair of access token / refresh token you need to follow the Authorization Code Flow (if you need a certain scope to be approved) or Client Credentials (if you just need to sign your request, like when fetching a certain playlist). Once you obtain them, you can use your access token and refresh it when it expires without having to show any login form.

Spotify API Authorization for cron job

I'm creating a node.js application that will update playlists (owned by an account in which I have credentials) daily. According to the Spotify documentation, to add tracks to a playlist (https://developer.spotify.com/web-api/add-tracks-to-playlist/), authorization must be supplied using oauth2.
I'm struggling to find a way to do this completely server side with no redirects/etc. It seems like if I can get a refresh token, I can just use that?
I've been looking at the spotify web api node module (https://github.com/thelinmichael/spotify-web-api-node), oauth.io, and the spotify api.
Any ideas would be appreciated! There is only one account that will have to be authenticated, so it could be hard-coded at least for now.
You've picked the correct authorization flow - Authorization Code, since you need an access token that's connected to the user who owns the playlists you're updating. This of course also gives you the ability to refresh the token whenever you need to. (The expiration time is one hour, but you don't need to refresh the access token until your application actually needs to use it.)
As a sidenote, the Client Credentials flow is meant for server to server communication that doesn't require a user's permission, e.g. to search, read a playlist, or retrieve new releases. The Implicit Grant flow is meant to be used in frontends, and doesn't allow you to refresh the token.
I'm struggling to find a way to do this completely server side with no redirects/etc. It seems like if I can get a refresh token, I can just use that?
Once you have the refresh token you can continue to use it to retrieve new access tokens, which can be done without any user interaction. You need to do some preparation work to retrieve the refresh token though.
Following the steps describing the Authorization Code flow, you first need to direct the playlist's owner to a URL on Spotify's account server.
The documentation contains the following example URL:
GET https://accounts.spotify.com/authorize/?client_id=5fe01282e44241328a84e7c5cc169165&response_type=code&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=user-read-private%20user-read-email&state=34fFs29kd09
Simply replace the client_id and redirect_uri with your application's information. Also modify the scope parameter to match the scopes you need, which from my understanding of your use case is playlist-read-private,playlist-modify-private,playlist-read-collaborative since you want to be able to read and modify all of the user's playlists. Supplying state is not required.
Using spotify-web-api-node you can generate this URL using the createAuthorizeURL method, but since you're only doing this once it's unnecessary to write code for it.
Instead, simply open the URL in your browser.
If done successfully, you'll be taken through a little login dance where your application asks for your permission to read and modify your playlists. When this is completed, Spotify's account service will redirect the browser to your redirect_uri URL with a code query parameter included as described in step 3 in the Authorization Guide.
However, since you're only doing this once, it would be enough to start a webserver on your own machine, set your application's redirect_uri to your localhost, and complete the login flow. Have a look at web-api-auth-examples for a ready-made node.js application that fires up an express server and reads the authorization code.
Once you've got the code, you can trade it for an access token using cURL as it's done in step #4 in the Authorization Guide, or use the code in the web-api-auth-examples repository.
Finally, with the tokens retrieved (step #5), you can start to use the Web API with the access token, and get a new one when it expires using the request in step #7.
spotify-web-api-node has a helper method to refresh the token. Search the main documentation for the refreshAccessToken method.
This use case is slightly mentioned in the FAQ section of the Authorization Guide.
As you said, you need to obtain a refresh token using the authorization code flow. For that you will need to carry out the OAuth process using your user account, the client_id of the app you have registered, and the scopes you need (it will vary depending on whether the playlist is private or public). Then, take the refresh token you have obtained and the client secret key of your app, and you can obtain access tokens without the need of the login form.
This related StackOverflow question might help too Spotify automated playlist management with PHP back-end and rate limits

Resources