Microsoft Graph NoPermissionsInAccessToken when trying to fetch contacts

Matej Martincevic 1 Reputation point
2020-02-17T11:51:02.867+00:00

So I'm trying to make this as simple as possible for myself, but for whatever reason I can't fetch contacts.

On the documentation page it is documented how to generally create the app and run it to get user data, which is great and I got that to work, however when I try fetching contacts in similar manner, no success.

First thing first: get the authorization code. So i ping "https://login.microsoftonline.com/6{tenant}/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fdetail&response_mode=query&scope=openid+offline_access+profile+user.read+Mail.ReadWrite+Contacts.ReadWrite"

Sure enough, I get the authorization code. Next up is getting AuthorizationCodeProvider for the IGraphServiceClient. So i plug the auth code, secret, id and all that:

AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(
    clientId,
    Arrays.asList("openid", "offline_access", "profile", "user.read", "Mail.ReadWrite", "Contacts.ReadWrite"),
    code,
    "http://localhost:8080/detail",
    NationalCloud.Global,
    tenant,
    secret);

IGraphServiceClient graphClient = GraphServiceClient
    .builder()
    .authenticationProvider(authProvider)
    .buildClient();

IContactCollectionPage contacts = graphClient.me().contacts()
    .buildRequest()
    .get();

The request is finally sent and I am greeted with this:

401 : Unauthorized
Strict-Transport-Security : max-age=31536000
Cache-Control : private
x-ms-ags-diagnostic : {"ServerInfo":{"DataCenter":"West Europe","Slice":"SliceC","Ring":"5","ScaleUnit":"000","RoleInstance":"AGSFE_IN_53"}}
client-request-id : e393d9d1-1eae-44b2-9956-2b97c0105b42
request-id : fecedee8-8b69-44b1-b300-5c9f71d3c427
Content-Length : 284
Date : Thu, 13 Feb 2020 13:12:27 GMT
Content-Type : application/json
{
  "error": {
    "code": "NoPermissionsInAccessToken",
    "message": "The token contains no permissions, or permissions can not be understood.",
    "innerError": {
      "request-id": "fecedee8-8b69-44b1-b300-5c9f71d3c427",
      "date": "2020-02-13T13:12:27"
    }
  }
}

I have given admin grants to what is necessary and more to the application, went to portal.azure.com -> App registration -> my application -> API permissions and added delegated Contacts.ReadWrite permission which is necessary for this endpoint. After that didn't work I even added Application Contacts.ReadWrite permission

I tried even just writing it all out , get access token from authorization code, open connection to https://graph.microsoft.com/users/me/contacts, put access token into request, but same result.

What am I doing wrong? This is driving me nuts.

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,466 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. FrankHu-MSFT 976 Reputation points
    2020-02-19T04:16:41.047+00:00

    Hey @Matej Martincevic

    It looks like you're not adding the access token to the graph client call. You can do this manually below.

    It will look something along the lines of this :

       var graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>  
            {  
                requestMessage  
                    .Headers  
                    .Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);  
                return Task.FromResult(0);  
            }));  
    

    Where access token is retrieved using the MSAL library using code such as :

                    result = await authContext.AcquireTokenAsync(resourceUri, clientId, new Uri(redirectUri), new PlatformParameters(PromptBehavior.Auto));  
    

    More info on the MSAL library can be found here : https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki

    Or you can try utilizing the MS Graph SDK's built in functionality that utilizes the MSAL library.

    You'll need to use the interactive auth provider constructor. See below :

    IPublicClientApplication clientApplication = PublicClientApplicationBuilder.Create(clientId).Build();  
    InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(clientApplication, scopes, Prompt.SelectAccount);  
    

    Remember to mark a response as answer if it's answered your question.

    Thanks,

    • Frank Hu