Tuesday, March 30, 2021

Create new site collections in Sharepoint Online using app-only permissions with certificate-based authentication (without appinv.aspx and client secret)

In the past if we needed to create site collections in Sharepoint Online we registered new SP app on appregnew.aspx page and granted Full control permissions on tenant level using appinv.aspx (alternatively instead of appregnew.aspx we could register new AAD app in Azure portal and then use it's clientId on appinv.aspx). But nowadays it is not preferred way to achieve this goal. In this article I will show ho to create new site collections using app-only permissions with certificate-based authentication (without appinv.aspx and client secret).

First of all we need to register new AAD app in Azure portal and grant Sites.FullControl.All API permissions (after granting permissions admin consent will be also needed):


Now for testing purposes let's try to create Modern Communication site using clientId and clientSecret:

using (var ctx = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext("https://{tenant}-admin.sharepoint.com", "{clientId}", "{clientSecret}"))
{
    ctx.RequestTimeout = Timeout.Infinite;
    var tenant = new Tenant(ctx);
    var properties = new SiteCreationProperties
    {
        Url = "https://{tenant}.sharepoint.com/sites/{siteUrl}",
        Lcid = 1033,
        TimeZoneId = 59,
        Owner = "{username}@{tenant}.onmicrosoft.com",
        Title = "{siteTitle}",
        Template = "SITEPAGEPUBLISHING#0",
        StorageMaximumLevel = 0,
        StorageWarningLevel = 0
    };

    var op = tenant.CreateSite(properties);
    ctx.Load(tenant);
    ctx.Load(op);
    ctx.ExecuteQueryRetry();

    ctx.Load(op, i => i.IsComplete);
    ctx.ExecuteQueryRetry();

    while (!op.IsComplete)
    {
        Thread.Sleep(30000);
        op.RefreshLoad();
        ctx.ExecuteQueryRetry();
        Console.Write(".");
    }
    Console.WriteLine("Site is created");
}

If we will try to run this code we will get Microsoft.SharePoint.Client.ServerUnauthorizedAccessException:

Access denied. You do not have permission to perform this action or access this resource.

Now let's try to create self-signed certificate like described here: Granting access via Azure AD App-Only. Then upload public key (.cer file) to our AAD app:


After that let's change C# example shown above to use certificate private key (.pfx file) and password for authentication. Code for creating site collection will remain the same:

using (var ctx = new OfficeDevPnP.Core.AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(
    "https://{tenant}-admin.sharepoint.com",
    "{clientId}",
    "{tenant}.onmicrosoft.com",
    @"C:\{certFileName}.pfx",
    "{certPassword}"))
{
    ctx.RequestTimeout = Timeout.Infinite;
    var tenant = new Tenant(ctx);
    var properties = new SiteCreationProperties
    {
        Url = "https://{tenant}.sharepoint.com/sites/{siteUrl}",
        Lcid = 1033,
        TimeZoneId = 59,
        Owner = "{username}@{tenant}.onmicrosoft.com",
        Title = "{siteTitle}",
        Template = "SITEPAGEPUBLISHING#0",
        StorageMaximumLevel = 0,
        StorageWarningLevel = 0
    };

    var op = tenant.CreateSite(properties);
    ctx.Load(tenant);
    ctx.Load(op);
    ctx.ExecuteQueryRetry();

    ctx.Load(op, i => i.IsComplete);
    ctx.ExecuteQueryRetry();

    while (!op.IsComplete)
    {
        Thread.Sleep(30000);
        op.RefreshLoad();
        ctx.ExecuteQueryRetry();
        Console.Write(".");
    }
    Console.WriteLine("Site is created");
}

This code will work and site collection will be successfully created. This is how you may create site collections in Sharepoint Online using app-only permissions and certificate-based authentication.

No comments:

Post a Comment