Claim type roles is missing in the access token when a HTTP POST call is made to https://login.microsoftonline.com/

Varun Umesh 1 Reputation point
2021-01-29T22:17:56.193+00:00

Folks!

I am a newbie to MS REST API and I am trying to access OneDrive via Microsoft Graph APIs. I have an enterprise office 365 account and here is what i have done so far :

Created an Azure App, exactly by following the steps mentioned here : https://learn.microsoft.com/en-us/graph/toolkit/get-started/add-aad-app-registration.

Added the following : https://learn.microsoft.com/en-us/onedrive/developer/rest-api/concepts/permissions_reference?view=odsp-graph-online Delegated API permissions.

Attaching a screenshot below:

![62022-screen-shot-2021-01-28-at-101843-pm.png][1]

Firstly, executed the below REST API to acquire the access token :

curl --location --request POST 'https://login.microsoftonline.com/
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,839 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Michael Taylor 49,251 Reputation points
    2021-01-29T22:24:17.477+00:00

    I'm a little confused why you're creating an app in Azure just to query the API. In general you don't need to do this. All you would need to do is make an OAuth request using a user that already has permissions. But I don't that this is the actual problem you're having.

    When you are connecting via OAuth you have to specify the scope(s) you want to request. You are missing that part of the request when getting the token. It should look something like this:

    --form 'scope=Files.Read.All'
    

    The above, when used when you request your bearer token, will request that the returned token have the given scope. When the token is subsequently passed to the API endpoint the endpoint will confirm that the token was granted the required scope before allowing the request.


  2. Michael Taylor 49,251 Reputation points
    2021-01-30T01:18:32.677+00:00

    (Responding with an answer because the comment reply isn't posting properly right now)

    Not every API uses scopes but those that do are for least privilege. As an example you may have a user who has permissions to do a lot but that doesn't mean you should be able to. Therefore when getting an access token you ask for the least privileges (scopes) you need. This helps keep things more secure.

    I personally don't know how OneDrive and your delegated permissions work because I don't know that I've ever tried to create an app in Azure to call the Graph API from MS. I'm used to working with the other MS APIs like Azure, Storage, etc. None of these require delegated permissions.

    The scopes are probably in the returned data but the bearer token is generally encrypted so what it contains is up to the OAuth server. It is important to note that claims and scopes are not the same thing. Scope is a request for a permission (and therefore the permission needed to call a particular endpoint) whereas claims are properties of the user such as their email address, phone number, etc.

    Having said all that I looked at calling OneDrive with client credentials and it mentions setting up an app and getting admin consent which I assume you did. However in the actual section 4 to get an access token it mentions you need to use the application ID URL for the scope. So refer to this example and make sure you're requesting the correct scope. I assume that this scope (a URL) then gives OneDrive access to the app's permissions (scopes).


  3. Michael Taylor 49,251 Reputation points
    2021-02-03T04:26:19.877+00:00

    Ok I've had some time to look into it. Graph does use scopes. You mentioned using CURL but I assume that is because you're playing around with the API to learn how it works. For an actual app you should just use the OneDrive SDK that wraps all this up nicely. You can find the documentation here. The walkthrough has you authenticate using oauth2 and it is using the standard oauth2 client credentials logic along with the scope(s) to use. You can take a look at the code that is doing the authentication to see how the HTTP call works if you want. Ultimately the clientId is your app ID which is accessible in the Azure portal when you created the app registration. The scopes will be the permissions you are requesting for the app and should encompass all the scopes you might need for the life of the app.

    Out of the box the OneDrive SDK doesn't have any authentication but the extension package MSA Auth Provider does. It is this code that would have the HTTP call you care about. Note that there is a separate provider for OneDrive Business that you'll need to use instead (I think it is AdalAuthenticationProvider). Once you have the auth provider configured and authenticated then you use the OneDriveClient to actually work with OneDrive.

    The linked documentation has a getting started sample that demonstrates the code but the actual auth looks something like this.

    //Scopes are the desired scopes
    //clientId is the GUID representing the application ID already configured in Azure
    var scopes = new[] { "user.read" };
    var authProvider = await AuthenticateAsync(clientId, scopes).ConfigureAwait(false);
    
    //Create the client
    var client = new OneDriveClient("https://api.onedrive.com/v1.0", authProvider);
    
    static async Task<IAuthenticationProvider> AuthenticateAsync ( string clientId, string[] scopes )
    {
         //Make a call using personal, for business use AdalAuthenticationProvider I believe
         var authProvider = new MsaAuthenticationProvider(clientId, "https://login.live.com/oauth20_desktop.srf", scopes);
    
         //This may trigger a UI so you might need to use a variant that allows a non-UI approach
         await authProvider.AuthenticateUserAsync().ConfigureAwait(false);
    
         return authProvider;
    }
    
    0 comments No comments