Sharepoint oAuth 2.0 retrieved token missing roles and scope

Larry Bellou 60 Reputation points
2025-01-10T14:19:51.79+00:00

Using code below I successfully retrieve an access token. Taking that token to jwt.ms , it does not have scp or roles though. So when I try and use it in postman url GET https://graph.microsoft.com/v1.0/sites/myCompany.sharepoint.com:/sites/SubscriberAcquisitionResourceCenter it fails. In c# it fails with 401 Unauthorized.

I have added the following permissions:

User's image

"error":{"code":"AccessDenied","message":"Either scp or roles claim need to be present in the token."
string siteUrl = "https://myCompany.sharepoint.com/sites/SubscriberAcquisitionResourceCenter";             string clientId = "********-****-****-****-********fe11";             
string tenantId = "********-****-****-****-********5a8f";             
string clientSecret = "***************"; // Updated client secret              
var authority = $"https://login.microsoftonline.com/{tenantId}/";             
var app = ConfidentialClientApplicationBuilder.Create(clientId)                 .WithClientSecret(clientSecret)                 
.WithAuthority(new Uri(authority))                 
.Build();              
var authResult = app.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" }).ExecuteAsync().Result;             
string accessToken = authResult.AccessToken;

Microsoft 365 and Office | SharePoint | Development
0 comments No comments
{count} votes

Accepted answer
  1. Ling Zhou_MSFT 23,620 Reputation points Microsoft External Staff
    2025-01-13T06:23:56.4466667+00:00

    Hi @Larry Bellou,

    Hope everything is going well.

    First, I looked at the C# code for your request token and the latest permissions you gave to your Azure AD App.

    We recommend that you remove the SharePoint related permissions and adopt only the Graph permissions as it is likely that the permission conflict is causing 401 error.

    I tested it in my environment:

    The permissions I have granted:

    User's image

    The code I tested (replace the variables with yours if you want to use it):

    using System;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    using Microsoft.Identity.Client;
    
    class Program
    {
        private static async Task Main(string[] args)
        {
            var tenantId = "your-tenant-id";
            var clientId = "your-client-id";
            var clientSecret = "your-client-secret";
    
            var authority = $"https://login.microsoftonline.com/{tenantId}";
            var scopes = new[] { "https://graph.microsoft.com/.default" };
    
            var app = ConfidentialClientApplicationBuilder.Create(clientId)
                .WithClientSecret(clientSecret)
                .WithAuthority(new Uri(authority))
                .Build();
    
            var authResult = await app.AcquireTokenForClient(scopes).ExecuteAsync();
            var accessToken = authResult.AccessToken;
    
            Console.WriteLine($"Access Token: {accessToken}");
    
            // Use the access token to call Microsoft Graph API
            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
            var response = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/sites/myCompany.sharepoint.com:/sites/SubscriberAcquisitionResourceCenter");
            var content = await response.Content.ReadAsStringAsync();
    
            Console.WriteLine($"Response: {content}");
        }
    }
    

    Got the right results:

    User's image

    If you have any questions, please do not hesitate to contact me.

    Moreover, if the issue can be fixed successfully, please click "Accept Answer" so that we can better archive the case and the other community members who are suffering the same issue can benefit from it.

    Your kind contribution is much appreciated.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Vasil Michev 119.7K Reputation points MVP Volunteer Moderator
    2025-01-10T16:28:10.7566667+00:00

    You are authenticating via client secret, i.e. using the client credentials flow. That flow only works with Application permissions, whereas based on the screenshot above, you have granted Delegate permissions on your app. Either grant the corresponding Application permissions instead, or obtain a token via any of the user-centric flows instead, such as the Auth code one: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.