Skip to content

Commit 1b4b24c

Browse files
robinmeureVesaJuvonen
authored andcommitted
Added KeyVault and KeyVault implementation (SharePoint#3770)
Provided an extra implementation of the certificate using Azure KeyVault in combination with an Azure Function
1 parent 22d3122 commit 1b4b24c

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

docs/solution-guidance/security-apponly-azuread.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Granting access via Azure AD App-Only
2+
23
When using SharePoint Online you can define applications in Azure AD and these applications can be granted permissions to SharePoint, but also to all the other services in Office 365. This model is the preferred model in case you’re using SharePoint Online, if you’re using SharePoint on-premises you have to use the SharePoint Only model via based Azure ACS as described in [here](security-apponly-azureacs.md).
34

45
> [!IMPORTANT]
56
> Azure Access Control (ACS), a service of Azure Active Directory (Azure AD), has been retired on November 7, 2018. This retirement does not impact the SharePoint Add-in model, which uses the `https://accounts.accesscontrol.windows.net` hostname (which is not impacted by this retirement). For more information, see [Impact of Azure Access Control retirement for SharePoint Add-ins](https://dev.office.com/blogs/impact-of-azure-access-control-deprecation-for-sharepoint-add-ins).
67
78
## Setting up an Azure AD app for app-only access
9+
810
In Azure AD when doing app-only you typically use a certificate to request access: anyone having the certificate and its private key can use the app and the permissions granted to the app. Below steps walk you through the setup of this model.
911

1012
You are now ready to configure the Azure AD Application for invoking SharePoint Online with an App Only access token. To do that, you have to create and configure a self-signed X.509 certificate, which will be used to authenticate your Application against Azure AD, while requesting the App Only access token. First you must create the self-signed X.509 Certificate, which can be created using the makecert.exe tool that is available in the Windows SDK or through a provided PowerShell script which does not have a dependency to makecert. Using the PowerShell script is the preferred method and is explained in this chapter.
@@ -208,6 +210,7 @@ In this sample the Sites.FullControl.All application permission require admin co
208210
![granting permissions to azure ad application](media/apponly/azureadapponly5.png)
209211

210212
## Using this principal with PnP PowerShell
213+
211214
If you want to use this AAD App Only principal with [PnP PowerShell](https://github.com/SharePoint/PnP-PowerShell), after you have installed the PnP PowerShell module, you can connect to your SharePoint Online environment using:
212215

213216
```powershell
@@ -217,6 +220,7 @@ Connect-PnPOnline -ClientId <$application client id as copied over from the AAD
217220
You can now perform operations through PnP PowerShell against your SharePoint Online environment using this certificate App Only trust.
218221

219222
## Using this principal in your application using the SharePoint PnP Sites Core library
223+
220224
In a first step, you add the SharePointPnPCoreOnline library nuget package: https://www.nuget.org/packages/SharePointPnPCoreOnline. Once that’s done you can use below code construct:
221225

222226
```csharp
@@ -241,6 +245,7 @@ namespace AzureADCertAuth
241245
}
242246
```
243247
## Using this principal in your Powershell script using the PnP Sites core library
248+
244249
When making use of Azure Automation Runbooks, first add the certificate (.pfx) using the Certificates option (under Shared Resources), then use the Get-AutomationCertificate cmdlet to retrieve the certificate to be used in the script.
245250

246251
> [!NOTE]
@@ -277,10 +282,68 @@ $clientContext.ExecuteQuery()
277282
$clientContext.Web.Title
278283
```
279284

285+
## Using this principal in your application and make use of the Azure KeyVault to store the certificate and retrieve it using an Azure Function
286+
287+
Add a [Managed Identity](https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity
288+
) to the Azure Function and give this identity access (GET permission on Secrets) to the [KeyVault](https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references).
289+
290+
Below there is a slightly different call to the same GetAzureADAppOnlyAuthenticatedContext method where we pass an actual certificate instead of a path to the certificate. An extra function is added to retrieve to certificate from the KeyVault using the managed identity of the Azure Function, this retrieval is seamless and transparent since the 'magic' happens in the AzureServiceTokenProvider.
291+
292+
```csharp
293+
static void Main(string[] args)
294+
{
295+
using (var cc = new AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(
296+
siteUrl,
297+
ApplicationId,
298+
tenant + ".onmicrosoft.com",
299+
GetKeyVaultCertificate("kv-spo", "AzureAutomationSPOAccess")))
300+
{
301+
cc.Load(cc.Web, p => p.Title);
302+
cc.ExecuteQuery();
303+
log.Info("Via PnP, we have site: " + cc.Web.Title);
304+
};
305+
}
306+
307+
308+
internal static X509Certificate2 GetKeyVaultCertificate(string keyvaultName, string name)
309+
{
310+
// Some steps need to be taken to make this work
311+
// 1. Create a KeyVault and upload the certificate
312+
// 2. Give the Function App the permission to GET certificates via Access Policies in the KeyVault
313+
// 3. Call an explicit access token request to the management resource to https://vault.azure.net and use the URL of our Keyvault in the GetSecretMethod
314+
if (keyVaultClient == null)
315+
{
316+
// this token provider gets the appid/secret from the azure function identity
317+
// and thus makes the call on behalf of that appid/secret
318+
var serviceTokenProvider = new AzureServiceTokenProvider();
319+
keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(serviceTokenProvider.KeyVaultTokenCallback));
320+
}
321+
322+
// Getting the certificate
323+
var secret = keyVaultClient.GetSecretAsync("https://" + keyvaultName + ".vault.azure.net/", name);
324+
325+
// Returning the certificate
326+
return new X509Certificate2(Convert.FromBase64String(secret.Result.Value));
327+
328+
// If you receive the following error when running the Function;
329+
// Microsoft.Azure.WebJobs.Host.FunctionInvocationException:
330+
// Exception while executing function: NotificationFunctions.QueueOperation--->
331+
// System.Security.Cryptography.CryptographicException:
332+
// The system cannot find the file specified.at System.Security.Cryptography.NCryptNative.ImportKey(SafeNCryptProviderHandle provider, Byte[] keyBlob, String format) at System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider)
333+
//
334+
// Please see https://stackoverflow.com/questions/31685278/create-a-self-signed-certificate-in-net-using-an-azure-web-application-asp-ne
335+
// Add the following Application setting to the AF "WEBSITE_LOAD_USER_PROFILE = 1"
336+
}
337+
338+
339+
```
340+
280341
## Using this principal with the Pnp Modernization Scanner
342+
281343
Now you have created the Azure Active Directory Application Registration, proceed with [following the steps here](https://docs.microsoft.com/en-us/sharepoint/dev/transform/modernize-scanner) to use this principal with the tool.
282344

283345
## FAQ
346+
284347
### Can I use other means besides certificates for realizing app-only access for my Azure AD app?
285348
No, all other options are blocked by SharePoint Online and will result in an Access Denied message.
286349

0 commit comments

Comments
 (0)