Kevin YANG
Kevin YANG

Reputation: 441

How to update share point online site collections using funtion app

I'm using azure function to develop some features about creating site collections.My steps as below:

  1. using admin to create site collections(by clientid and client secret)
  2. get the new URl client context to update some informations such as group members site owners etc

I'm now facing a problem that firstly I use use account and password to get the new client context and then update site property but now can not use it cause the new corporation policy. How can i improve this method to fix this issue?

public ClientContext GetClientContextByCredential(SharePointOnlineCredentials cred, bool tryNewSite)
        {
            ClientContext ctx = ContextInit;
            try
            {
                ctx.Credentials = cred;
                Web web = ctx.Web;
                ctx.Load(web, w => w.Url);
                ctx.ExecuteQuery();

                return ctx;
            }
            catch (Exception ex)
            {
                ctx = null;
                if (_logHelper != null)
                {
                    if (tryNewSite)
                    {
                        _logHelper.writeLog(ex.Message, TraceLevel.Info, ex);
                    }
                    else
                        _logHelper.writeLog(ex.Message, TraceLevel.Error, ex);
                }
                return ctx;
            }
        }

such error will happer when use SharePointOnlineCredentials

The remote server returned an error: (401) Unauthorized.

Upvotes: 0

Views: 198

Answers (1)

Jim Xu
Jim Xu

Reputation: 23141

If you want to use Azure AD application to connect SharePoint online, please refer to the following steps

  1. Create an Azure AD application
Connect-AzureAD 

# Create the self signed cert if you have the cert, please skip it
$currentDate = Get-Date
$endDate  = $currentDate.AddYears(1)
$notAfter  = $endDate.AddYears(1)
$pwd  = "<password>"
$thumb = (New-SelfSignedCertificate -CertStoreLocation cert:\localmachine\my -DnsName com.foo.bar -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $notAfter).Thumbprint
$pwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText
Export-PfxCertificate -cert "cert:\localmachine\my\$thumb" -FilePath c:\temp\examplecert.pfx -Password $pwd

# Load the certificate
$cert  = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("C:\temp\examplecert.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())


# Create the Azure Active Directory Application
$application = New-AzureADApplication -DisplayName "test123" -IdentifierUris "https://test123"
New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier "Test123" -StartDate $currentDate -EndDate $endDate -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
  1. Configure permissions via Azure Portal enter image description here

  2. Upload cert to Azure key vault

$Password = ConvertTo-SecureString -String "123" -AsPlainText -Force
Import-AzKeyVaultCertificate -VaultName "ContosoKV01" -Name "ImportCert01" -FilePath "C:\temp\examplecert.pfx" -Password $Password
  1. Configure Azure function

    a. Configure MSI for function app enter image description here enter image description here

    b. Create an access policy in Key Vault for the application identity you created earlier. Enable the "Get" secret permission on this policy.

    c. code

    public ClientContext GetClientContextByCredential()
          {
              ClientContext ctx = ContextInit;
              try
              {
                   ctx  = new AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(
          siteUrl,
          ApplicationId,
          tenant + ".onmicrosoft.com",
          GetKeyVaultCertificate("kv-spo", "AzureAutomationSPOAccess")))
          {
          ctx  .Load(cc.Web, p => p.Title);
          ctx  .ExecuteQuery();
    
                  return ctx;
              }
              catch (Exception ex)
              {
                  ctx = null;
                  if (_logHelper != null)
                  {
                      if (tryNewSite)
                      {
                          _logHelper.writeLog(ex.Message, TraceLevel.Info, ex);
                      }
                      else
                          _logHelper.writeLog(ex.Message, TraceLevel.Error, ex);
                  }
                  return ctx;
              }
          }
    
     internal static X509Certificate2 GetKeyVaultCertificate(string keyvaultName, string name)
    {
    
    
          var serviceTokenProvider = new AzureServiceTokenProvider();
         var  keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(serviceTokenProvider.KeyVaultTokenCallback));
    
    
      // Getting the certificate
      var secret = keyVaultClient.GetSecretAsync("https://" + keyvaultName + ".vault.azure.net/", name);
    
      // Returning the certificate
      return new X509Certificate2(Convert.FromBase64String(secret.Result.Value));
    
    
    }
    
    

For more details, please refer to

https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread

https://learn.microsoft.com/en-us/archive/blogs/richard_dizeregas_blog/performing-app-only-operations-on-sharepoint-online-through-azure-ad

Upvotes: 1

Related Questions