question

MatejMartincevic-5230 avatar image
0 Votes"
MatejMartincevic-5230 asked ·

Microsoft Graph NoPermissionsInAccessToken when trying to fetch contacts

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≻ope=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.

azure-ad-graph
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

FrankHuMSFT-3200 avatar image
0 Votes"
FrankHuMSFT-3200 answered ·

Hey @MatejMartincevic-5230

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

· 1 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hey, sorry for the late reply. I've been shifted around projects a bit.

Is this really the case? When I look through the class, in the constructor of AuthorizationCodeProvider I can see that it handles requesting the access token by itself. I'd hope I wouldn't have to do anything else with it. And I didn't have any problem fetching general user data, and that too requires an access token, right? For example, if I replace the part where i fetch contacts with User user = graphClient.me().buildRequest().get();, I get data normally.

This really has me confused.

0 Votes 0 · ·