1

Context

I am developing a simple application that requires to receive List Data from a company Online SharePoint site. In order to make REST requests, I must first retrieve an access token from Microsoft's access control service. Despite attempting some tutorials and reading documentation, I am new to REST/HTTP am am failing to do so.

What have I tried?

  • Used SharePoint appregnew.aspx to register my app, and generate "Client ID" and "Client Secret" values. https://[sitename].sharepoint.com/_layouts/15/appregnew.aspx
  • Used Sharepoint appinv.aspx to authorize my app with read control and generate a "Tenant ID". https://[sitename].sharepoint.com/_layouts/15/appinv.aspx
<AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read"/>
</AppPermissionRequests>
  • Used SharePoint AppPrincipals.aspx to verify Tenant ID. https://[sitename].sharepoint.com/_layouts/15/AppPrincipals.aspx
  • Attempted several methods of formatting the request with the following being the latest:

Updated

// Variables removed for security
class Program
{
    static void Main(string[] args)
    {               
        WebRequest myWebRequest;
        string stGetAccessTokenUrl = "https://accounts.accesscontrol.windows.net/{0}/tokens/OAuth/2";

        string tenantID         = "myTenantID";
        string resourceID       = "00000003-0000-0ff1-ce00-000000000000";
        string stClientID       = "myClientID";
        string stClientSecret   = "myClientSecret";
        string stSiteDomain     = "[myCompany].sharepoint.com";

        // URL Format
        stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);
        myWebRequest = WebRequest.Create(stGetAccessTokenUrl);
        myWebRequest.ContentType = "application/x-www-form-urlencoded";
        myWebRequest.Method = "POST";

        // Add the below body attributes to the request
        var postData = "grant_type=client_credentials";
        postData += "&client_id=" + stClientID + "@" + tenantID;
        postData += "&client_secret=" + stClientSecret;
        postData += "&resource=" + resourceID + "/" + stSiteDomain + "@" + tenantID;
        var data = Encoding.ASCII.GetBytes(postData);

        using (var stream = myWebRequest.GetRequestStream())
        {
            stream.Write(data, 0, data.Length);
        }
            
        var response = (HttpWebResponse)myWebRequest.GetResponse();
    }
}

What doesn't work?

I receive a 401 Unauthorized error despite the app having been assigned permissions.

Any help would be greatly appreciated!

2 Answers 2

0

Apologies, I forgot to return to this question upon resolving the issue. Credit to "Michael Han" within the comments of his own answer.

Answer

By default, the SharePoint app-only permissions is disabled for the tenant. A tenant administrator must first run the following cmdlet in PowerShell:

Set-SPOTenant -DisableCustomAppAuthentication $false

This parameter supersedes all other privilege settings and must first be configured.

Sign up to request clarification or add additional context in comments.

Comments

-1

You could refer to this article to get the access token : https://social.technet.microsoft.com/wiki/contents/articles/51982.sharepoint-read-online-list-data-from-c-console-application-using-access-token.aspx

 #region Get Access Token using TenantID and App secret ID & Password
 // URL Format
 //https://accounts.accesscontrol.windows.net/tenant_ID/tokens/OAuth/2 Jump
 
 stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);
 myWebRequest = WebRequest.Create(stGetAccessTokenUrl);
 myWebRequest.ContentType = "application/x-www-form-urlencoded";
 myWebRequest.Method = "POST";
  
   
 // Add the below body attributes to the request
 /*
  *  grant_type  client_credentials  client_credentials
  client_id  ClientID@TenantID 
  client_secret  ClientSecret 
  resource  resource/SiteDomain@TenantID  resourceid/abc.sharepoint.com@tenantID
  */
  
 
 var postData = "grant_type=client_credentials";
 postData += "&client_id=" + stClientID +"@" +tenantID;
 postData += "&client_secret=" + stClientSecret;
 postData += "&resource=" + resourceID + "/" + stSiteDomain + "@" + tenantID;
 var data = Encoding.ASCII.GetBytes(postData);
 
 using (var stream = myWebRequest.GetRequestStream())
 {
  stream.Write(data, 0, data.Length);
 }
 var response = (HttpWebResponse)myWebRequest.GetResponse();
 
 var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
 
 string[] stArrResponse = responseString.Split(',');
  
 //get the access token and expiry time ,etc
  
 foreach(var stValues in stArrResponse)
 {
   
  if(stValues.StartsWith("\"access_token\":"))
  {
  //Console.WriteLine(" Result => " + stValues);
  accessToken = stValues.Substring(16);
  //Console.WriteLine(" Result => " + accessToken);
  accessToken = accessToken.Substring(0,accessToken.Length-2);
  // Console.WriteLine(" Result => " + accessToken);
  }
 }

6 Comments

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
Thanks for the mentioning, I have added it.
Thanks for your input. I work through this article again from scratch and have updated my post to include an extraction of the code. I do however still receive an error.
It could be that the SharePoint app-only permissions is disabled for you tenant. Please run the below cmdlet to enable it: Set-SPOTenant -DisableCustomAppAuthentication $false
This looks very likely to be the issue! Thank you. I’ll need to address it with my tenant administrator and come back to you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.