Hi,
I followed the Build service and daemon apps in Office 365 and Performing app-only operations on SharePoint Online through Azure AD document to create a windows console application to communicate to SPO using Azure AD App-only token approach and got the above error message. the following is my steps:
- Created a Azure AD application and specified the following settings:
- Name: sharepointappidtest
- Type: Web application and/or Web API
- Sign-On URL: https://xyz.sharepoint.com
- App ID URI: https://xyz.sharepoint.com
- Configure this Azure AD application’s “permission to other applications” as the following:
- Windows Azure Active Directory: “Read Directory data” [Application permission]
- Office 365 SharePoint Online: “Have Full control of all site collections” [Application permission] and “Read and write managed metadata” [Application permission].
- Created a self-signed certificate and run the PS from those two documents to get key, and thumbnail key
- Downloaded manigest.json, updated “keyCredentials” value and uploaded it back.
- Created a windows console application. Added Microsoft.IdentityModel.Clients.ActiveDirectory and Newtonsoft.Json libraries.
- The following is my code:
static void Main(string[] args)
{
doStuffInOffice3651().Wait();
}
private async static Task doStuffInOffice3651()
{
string clientId = "[Azure AD application client id]";
string key = "xxxx"; //certificate password
//set the authentication context
//you can do multi-tenant app-only, but you cannot use /common for authority…must get tenant ID
//string authority = "https://login.microsoftonline.com/[tenant].onmicrosoft.com/oauth2/authorize";
string authority = "https://login.windows.net/[tenant].onmicrosoft.com";
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
//read the certificate private key from the executing location
//NOTE: This is a hack…Azure Key Vault is best approach
var certPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
//certPath = certPath.Substring(0, certPath.LastIndexOf('\\')) + "\\O365AppOnly_private.pfx";
certPath = @"C:\OfficeDevPnP.PartnerPack.SiteProvisioning\Certs\OfficeDevPnPCert.pfx";
var certfile = System.IO.File.OpenRead(certPath);
var certificateBytes = new byte[certfile.Length];
certfile.Read(certificateBytes, 0, (int)certfile.Length);
X509Certificate2 cert = new X509Certificate2(certPath, key, X509KeyStorageFlags.MachineKeySet);
//var cert = new X509Certificate2(
// certificateBytes,
// key,
// X509KeyStorageFlags.Exportable |
// X509KeyStorageFlags.MachineKeySet |
// X509KeyStorageFlags.PersistKeySet); //switchest are important to work in webjob
ClientAssertionCertificate cac = new ClientAssertionCertificate(clientId, cert);
//get the access token to SharePoint using the ClientAssertionCertificate
Console.WriteLine("Getting app - only access token to SharePoint Online");
var authenticationResult = await authenticationContext.AcquireTokenAsync("https://xyz.sharepoint.com/", cac);
var token = authenticationResult.AccessToken;
Console.WriteLine("App - only access token retreived");
//perform a post using the app-only access token to add SharePoint list item in Attendee list
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
client.DefaultRequestHeaders.Add("Accept", "application/json; odata = verbose");
string url = "https://xyz.sharepoint.com/_api/web/Lists/getbytitle('TestLog')";
using (HttpResponseMessage response = await client.GetAsync(url))
{
if (!response.IsSuccessStatusCode)
Console.WriteLine("ERROR: SharePoint ListItem Creation Failed!");
else
Console.WriteLine("SharePoint ListItem Created!");
}
Console.ReadLine();
}I was able to get token without any problems. But no matter how I did, I always got the following 401 error message for REST API call:
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{x-ms-diagnostics: 3001000;reason="There has been an error authenticating the request.";category="invalid_client"
SPRequestGuid: 25eb839d-0020-3000-0b4e-92f6dca2b3aa
request-id: 25eb839d-0020-3000-0b4e-92f6dca2b3aa
Strict-Transport-Security: max-age=31536000
X-FRAME-OPTIONS: SAMEORIGIN
SPRequestDuration: 212
SPIisLatency: 3
MicrosoftSharePointTeamServices: 16.0.0.5326
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
Date: Tue, 07 Jun 2016 20:19:53 GMT
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
Server: Microsoft-IIS/8.5
WWW-Authenticate: Bearer realm="6f423eb7-7932-4e19-ae14-fa375038681b",client_id="00000003-0000-0ff1-ce00-000000000000",trusted_issuers="00000001-0000-0000-c000-000000000000@*,https://sts.windows.net/*/,00000003-0000-0ff1-ce00-000000000000@90140122-8516-11e1-8eff-49304924019b",authorization_uri="https://login.windows.net/common/oauth2/authorize"
X-Powered-By: ASP.NET
Content-Length: 453
}}
can anyone point me out what the problem is?









