question

sp13test-6829 avatar image
0 Votes"
sp13test-6829 asked MichaelHan-MSFT answered

Sharepoint Rest API Authentication issues with Access Token Header

I'm trying to implement a C# program to connect to Sharepoint API through modern authentication (Client ID\ Client Secret).

I've registered an APP with Sharepoint overall permissions on Azure Active Directory, in order to generate Client Id and Client Secret.

Next steps should be retrieval of the Access Token from the Microsoft login page, and then construction of all following requests using the bearing token I've generated.

Retrieval of the Access Token just works fine. The problem is when I try to include the token in the authorization header on the following calls.

I always get 401 Unhautorized when building my requests from code. Debugging the response content, what I get is "x-ms-diagnostics: 3000006;reason="Token contains invalid signature"; category"invalid_client". Instead if I try to replicate the call in Postman I get the following error "{"error_description":"Unsupported security token."}".

I provide my code below. Does anybody knows what is going on?

      var b2cAuthUri = "https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/token";
        
                 var client = new HttpClient();
        
                 var dict = new Dictionary<string, string>();
                 dict.Add("Content-Type", "application/x-www-form-urlencoded");
                 dict.Add("grant_type", "client_credentials");
                 dict.Add("client_id", clientId);
                 dict.Add("client_secret", clientSecret);
                 dict.Add("scope", scope);
        
                 // Execute post method
                 using (var methodResp = client.PostAsync(b2cAuthUri, new FormUrlEncodedContent(dict)))
                 {
        
                     var callResult = methodResp.Result.Content.ReadAsStringAsync().Result;
                     if (!string.IsNullOrEmpty(callResult))
                     {
                         //I have my Access Token here :)
                         using (MemoryStream DeSerializememoryStream = new MemoryStream())
                         {
                               
        
                             //initialize DataContractJsonSerializer object and pass custom token class type to it
                             DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AccessToken));
        
                             //user stream writer to write JSON string data to memory stream
                             StreamWriter writer = new StreamWriter(DeSerializememoryStream);
                             writer.Write(callResult);
                             writer.Flush();
        
                             DeSerializememoryStream.Position = 0;
                             //get the Desrialized data in object of type Student
                             AccessToken SerializedObject = (AccessToken)serializer.ReadObject(DeSerializememoryStream);
                             var tokenBytes = System.Text.Encoding.UTF8.GetBytes(SerializedObject.access_token);
                             //64bit serialized token
                             var tokenBase64 = System.Convert.ToBase64String(tokenBytes);
        
                             //Here I try to make a call with the access token as header
                             var testURI = "https://myorg.sharepoint.com/sites/crmkb/_api/web/lists";
        
                             HttpWebRequest testReq = (HttpWebRequest)HttpWebRequest.Create(testURI);
                             testReq.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + tokenBase64);
                             testReq.Method = "GET";
                             //This fails on 401 code
                             HttpWebResponse response = (HttpWebResponse)testReq.GetResponse();
        
        
                         }
                     }
                 }
office-sharepoint-server-development
5 |1600 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

MichaelHan-MSFT avatar image
0 Votes"
MichaelHan-MSFT answered

Hi @sp13test-6829 ,

The way you used to get access token is for Graph API authentication, it would not work for SharePoint authentication.

In Postman, you could get the access token like this:

 Grant Type :         Authorization Code 
 Callback Url :       this should be the AAD App redirect Url 
 Auth URL :           https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2F<tenant_name>.sharepoint.com  
 Access Token URL :   https://login.microsoftonline.com/common/oauth2/token  
 Client ID :          <client_ID>  
 Client Secret :      <Client-secret>  

88489-image.png

When you click Get Access Token, it would request you to sign in. After signing in, you would access it successfully.

Besides, you could use certification option for authentication: https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread

Reference: https://www.ludovicmedard.com/use-postman-and-azure-ad-to-send-rest-request-to-sharepoint-online/

5 |1600 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.