Intro

In this post I am going to show how to create Azure Active Directory app and call SharePoint Online rest API from C# code.

Prerequisites

You need to have Azure Subscription and Office 365 Dev Tenant.

Code

First of all we need to make sure your Azure AD is associated with Office 365 Tenant. Go here to associate an existing Azure subscription with your Office 365 account in case you don't have access to your Office 365 Tenant Active Directory.

Now we need to register our app in Azure AD, more information can be found at Integrating applications with Azure Active Directory and Performing app-only operations on SharePoint Online through Azure AD

First of all, I want to emphasize that it is not possible to make app-only calls to SharePoint Online using only Client Secret and Client ID. So we will need to use a management certificate.

Generate certificate

Open Visual Studion Command prompt. If you use VS2015 and Windows 10, search for Developer Command Prompt for VS2015 and type makecert. You should get something similar to this:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/01-dev-command-prompt-makecert-test.png

makecert is usually automatically installed with VS2015, but sometimes it is missing, check the following link if it is your case Makecert missing from Windows 10 and Visual Studio 2015 install?

To generate the management certificate run the following command:

makecert -r -pe -n "CN=O365S2S" -b 01/01/2016 -e 01/01/2020 -ss my -len 2048

If you are reading this in 2020, adjust your certificate expiry date accordingly :)

Export .CER certificate

Now we need to export the certificate, go to MMC \ Certificates \ My user account \ Personal and find O365S2S certificate:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/02-mmc-certificate.png

It is very important to understand the difference between .cer and .pfx certificate files, in our case we need both. Right click on the O365S2S certificate and select All Tasks \ Export .... We need to get .cer file first. Follow the following steps:

Select 'No, do not export the private key'.

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/03-no-private-key.png

Choose DER-encoded binary X.509 (.CER)

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/04-der-certificate.png

Then choose a file name for the certificate and finish the export.

Export .PFX certificate

Now we need to get .PFX certificate which contains the private key. Right click on the O365S2S certificate and select All Tasks \ Export .... Follow the following steps:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/05-with-private-key.png

Make sure you checked the following checkboxes:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/06-pfx-certificate.png

Specify password for the certificate:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/07-pfx-specify-password.png

Then choose a file name for the certificate and finish the export.

Register the application in Azure Active Directory

Before you start, make sure that you use the same Active Directory that is used by your Office 365 tenant. You can switch between different Active Directories in Azure Portal, also you have to use old Azure Portal, it is still imposible to add an app using new portal.

Go to Active Directory, select Applications link at the top and click Add at the bottom of the page:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/08-add-app.png

Select 'Add an application my organization is developing'.

I am going to use this Azure Active Directory application for development purposes, so I will give it a generic name, but you should use name that represents the application.

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/09-app-name.png

I use dummy URL on the next screen, it should be url to home page of your application, you can update it at any time:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/10-app-properties.png

Now, when app is created, set app permissions to other applications:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/11-add-app-permissions-to-other-apps.png

Select Office 365 SharePoint Online, that's the only app that we need to add right now.

Now let's give our app FULL CONTROL over Azure Active Directory:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/13-full-control-over-ad.png

And Office 365 SharePoint Online:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/12-full-control-over-spo.png

Click save and go back to New Azure Portal.

Now it is time to manualy update the application manifest with values from .cer certificate. Run the following script against your exported certificate:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 "O365S2S.cer"
"value: $([System.Convert]::ToBase64String($cert.GetRawCertData()))"
"customKeyIdentifier: $([System.Convert]::ToBase64String($cert.GetCertHash()))"
"keyId: $([System.Guid]::NewGuid().ToString())"

Click Edit Manifest in New Azure Portal:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/14-edit-manifest.png

Find keyCredentials section and replace corresponding values with values generated by script. After save you should get something similar to the following:

https://raw.githubusercontent.com/boades/boades-blog-content/master/03-azure/02-azure-o365-serverless-integration/01-how-to-use-azure-ad-app-for-app-only-communications/15-edit-manifest-2.png

Now we are ready to test our app from code.

Testing

Create a new Console Application and install ADAL.NET nuget package:

Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory

And SharePoint Online CSOM package:

Install-Package Microsoft.SharePointOnline.CSOM

And then copy-paste the follow code, adjust values to your needs. Don't forget to specify valid path to .pfx certifiate:

class Program
{
    private static string ClientId = "068f1af4-ee37-45a8-885d-deec513c52d8";
    private static string Cert = "O365S2S.pfx";
    private static string CertPassword = "O365S2S";
    private static string Authority = "https://login.windows.net/oleksiionsoftware.onmicrosoft.com/";
    private static string Resource = "https://oleksiionsoftware.sharepoint.com/";
    private static string SpoSite = "https://oleksiionsoftware.sharepoint.com/sites/dev";

    static void Main(string[] args)
    {
        Run().Wait();
    }

    private async static Task Run()
    {
        var authenticationContext = new AuthenticationContext(Authority, false);
        
        var cert = new X509Certificate2(System.IO.File.ReadAllBytes(Cert),
            CertPassword,
            X509KeyStorageFlags.Exportable |
            X509KeyStorageFlags.MachineKeySet |
            X509KeyStorageFlags.PersistKeySet);

        var authenticationResult = await authenticationContext.AcquireTokenAsync(Resource, new ClientAssertionCertificate(ClientId, cert));
        var token = authenticationResult.AccessToken;

        using (var ctx = new ClientContext(SpoSite))
        {
            ctx.ExecutingWebRequest += (s, e) =>
            {
                e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + authenticationResult.AccessToken;
            };

            ctx.Load(ctx.Web.Lists);
            ctx.ExecuteQuery();
        }
    }
}

This code loads a list of lists from SpoSite, it will work fine if you do everything correctly.

Summary

In this post I have described steps required to generate a certificate, add a new app to Azure Active Directory, setup required permissions and make calls to Office 365 SharePoint Online REST Api using SharePoint CSOM library. In the next post I am going to show how to use this approach to provision SharePoint Online artifacts from Azure Function.


;