Concedendo acesso somente por meio do aplicativo Azure AD

Ao usar o SharePoint Online, você pode definir aplicativos no Azure AD e a esses aplicativos podem ser concedidas permissões para o SharePoint, mas também para todos os outros serviços no Office 365. Esse modelo é o modelo preferencial caso você esteja usando o SharePoint Online, se estiver usando o SharePoint local, precisará usar o modelo Somente do SharePoint por meio do Azure ACS baseado, conforme descrito aqui.

Importante

O uso do Azure ACS (Controle de Acesso Services) para o SharePoint Online foi desativado a partir de 27 de novembro de 2023, confira o comunicado completo de aposentadoria para saber mais. O uso do ACS do Azure fora do contexto do SharePoint já foi desativado em 7 de novembro de 2018 e agora é o fim da vida útil.

A aposentadoria significa que o recurso não receberá novos investimentos, mas ainda tem suporte. O fim da vida útil significa que o recurso será descontinuado e não está mais disponível para uso.

Configurando um aplicativo Azure AD para acesso somente a aplicativos

Em Azure AD ao fazer somente aplicativo, você normalmente usa um certificado para solicitar acesso: qualquer pessoa que tenha o certificado e sua chave privada pode usar o aplicativo e as permissões concedidas ao aplicativo. As etapas abaixo orientam você sobre a configuração deste modelo.

Agora você está pronto para configurar o aplicativo Azure AD para invocar o SharePoint Online com um token de acesso somente aplicativo. Para fazer isso, você precisa criar e configurar um certificado X.509 autoassinado, que será usado para autenticar seu aplicativo no Azure AD, ao solicitar o token de acesso Somente aplicativo. Primeiro, você deve criar o Certificado X.509 autoassinado, que pode ser criado usando a ferramenta makecert.exe que está disponível no SDK do Windows, por meio de um script fornecido do PowerShell que não tem uma dependência para fazer certificação ou com um comando PnP PowerShell. Usar o script do PowerShell é o método preferencial e é explicado neste capítulo.

Importante

É importante que você execute os scripts abaixo com privilégios de administrador.

Para criar um certificado autoassinado com este script:

.\Create-SelfSignedCertificate.ps1 -CommonName "MyCompanyName" -StartDate 2017-10-01 -EndDate 2019-10-01

Observação

As datas são fornecidas no formato de data ISO: YYYY-MM-dd

O algoritm da chave de certificado deve ser RSA, este é o único algoritmo com suporte atualmente

O script real pode ser copiado a partir daqui:

#Requires -RunAsAdministrator
<#
.SYNOPSIS
Creates a Self Signed Certificate for use in server to server authentication
.DESCRIPTION
.EXAMPLE
PS C:\> .\Create-SelfSignedCertificate.ps1 -CommonName "MyCert" -StartDate 2015-11-21 -EndDate 2017-11-21
This will create a new self signed certificate with the common name "CN=MyCert". During creation you will be asked to provide a password to protect the private key.
.EXAMPLE
PS C:\> .\Create-SelfSignedCertificate.ps1 -CommonName "MyCert" -StartDate 2015-11-21 -EndDate 2017-11-21 -Password (ConvertTo-SecureString -String "MyPassword" -AsPlainText -Force)
This will create a new self signed certificate with the common name "CN=MyCert". The password as specified in the Password parameter will be used to protect the private key
.EXAMPLE
PS C:\> .\Create-SelfSignedCertificate.ps1 -CommonName "MyCert" -StartDate 2015-11-21 -EndDate 2017-11-21 -Force
This will create a new self signed certificate with the common name "CN=MyCert". During creation you will be asked to provide a password to protect the private key. If there is already a certificate with the common name you specified, it will be removed first.
#>
Param(

   [Parameter(Mandatory=$true)]
   [string]$CommonName,

   [Parameter(Mandatory=$true)]
   [DateTime]$StartDate,

   [Parameter(Mandatory=$true)]
   [DateTime]$EndDate,

   [Parameter(Mandatory=$false, HelpMessage="Will overwrite existing certificates")]
   [Switch]$Force,

   [Parameter(Mandatory=$false)]
   [SecureString]$Password
)

# DO NOT MODIFY BELOW

function CreateSelfSignedCertificate(){

    #Remove and existing certificates with the same common name from personal and root stores
    #Need to be very wary of this as could break something
    if($CommonName.ToLower().StartsWith("cn="))
    {
        # Remove CN from common name
        $CommonName = $CommonName.Substring(3)
    }
    $certs = Get-ChildItem -Path Cert:\LocalMachine\my | Where-Object{$_.Subject -eq "CN=$CommonName"}
    if($certs -ne $null -and $certs.Length -gt 0)
    {
        if($Force)
        {

            foreach($c in $certs)
            {
                remove-item $c.PSPath
            }
        } else {
            Write-Host -ForegroundColor Red "One or more certificates with the same common name (CN=$CommonName) are already located in the local certificate store. Use -Force to remove them";
            return $false
        }
    }

    $name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
    $name.Encode("CN=$CommonName", 0)

    $key = new-object -com "X509Enrollment.CX509PrivateKey.1"
    $key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
    $key.KeySpec = 1
    $key.Length = 2048
    $key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
    $key.MachineContext = 1
    $key.ExportPolicy = 1 # This is required to allow the private key to be exported
    $key.Create()

    $serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
    $serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1") # Server Authentication
    $ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
    $ekuoids.add($serverauthoid)
    $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
    $ekuext.InitializeEncode($ekuoids)

    $cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
    $cert.InitializeFromPrivateKey(2, $key, "")
    $cert.Subject = $name
    $cert.Issuer = $cert.Subject
    $cert.NotBefore = $StartDate
    $cert.NotAfter = $EndDate
    $cert.X509Extensions.Add($ekuext)
    $cert.Encode()

    $enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
    $enrollment.InitializeFromRequest($cert)
    $certdata = $enrollment.CreateRequest(0)
    $enrollment.InstallResponse(2, $certdata, 0, "")
    return $true
}

function ExportPFXFile()
{
    if($CommonName.ToLower().StartsWith("cn="))
    {
        # Remove CN from common name
        $CommonName = $CommonName.Substring(3)
    }
    if($Password -eq $null)
    {
        $Password = Read-Host -Prompt "Enter Password to protect private key" -AsSecureString
    }
    $cert = Get-ChildItem -Path Cert:\LocalMachine\my | where-object{$_.Subject -eq "CN=$CommonName"}

    Export-PfxCertificate -Cert $cert -Password $Password -FilePath "$($CommonName).pfx"
    Export-Certificate -Cert $cert -Type CERT -FilePath "$CommonName.cer"
}

function RemoveCertsFromStore()
{
    # Once the certificates have been been exported we can safely remove them from the store
    if($CommonName.ToLower().StartsWith("cn="))
    {
        # Remove CN from common name
        $CommonName = $CommonName.Substring(3)
    }
    $certs = Get-ChildItem -Path Cert:\LocalMachine\my | Where-Object{$_.Subject -eq "CN=$CommonName"}
    foreach($c in $certs)
    {
        remove-item $c.PSPath
    }
}

if(CreateSelfSignedCertificate)
{
    ExportPFXFile
    RemoveCertsFromStore
}

Você será solicitado a fornecer uma senha para criptografar sua chave privada e o . Arquivo PFX e . O arquivo CER será exportado para a pasta atual.

Observação

O certificado autoassinado também pode ser gerado por meio do comando New-PnPAzureCertificate .

A próxima etapa é registrar um aplicativo Azure AD no locatário do Azure Active Directory vinculado ao seu locatário Office 365. Para fazer isso, abra o Centro de Office 365 Administração (https://admin.microsoft.com) usando a conta de um usuário membro do grupo de administradores globais de locatários. Clique no link "Azure Active Directory" que está disponível no grupo "Administração centros" na visão de árvore do lado esquerdo do Centro de Office 365 Administração. Na guia do novo navegador que será aberta, você encontrará o Microsoft portal do Azure. Se for a primeira vez que você acessar o portal do Azure com sua conta, será necessário registrar uma nova assinatura do Azure, fornecendo algumas informações e um cartão de crédito para qualquer necessidade de pagamento. Mas não se preocupe, para brincar com Azure AD e registrar um aplicativo Office 365 você não pagará nada. Na verdade, são recursos gratuitos. Depois de ter acesso ao portal do Azure, selecione a seção "Azure Active Directory" e escolha a opção "Registros de aplicativo". Confira a próxima figura para obter mais detalhes.

mostra o portal de anúncios do Azure

Na guia "Registros de aplicativo", você encontrará a lista de aplicativos Azure AD registrados em seu locatário. Clique no botão "Novo registro" na parte superior esquerda da folha. Em seguida, forneça um nome para seu aplicativo e clique em "Registrar" na parte inferior da folha.

cria um novo aplicativo de anúncio do azure

Importante

Depois que o aplicativo tiver sido criado, copie a ID do "Aplicativo (cliente)", pois você precisará dele mais tarde.

Agora clique em "permissões de API" na barra de menus à esquerda e clique no botão "Adicionar uma permissão". Uma nova folha será exibida. Aqui você escolhe as permissões que concederá a este aplicativo. Escolha ou seja:

  • SharePoint
    • Permissões de aplicativos
      • Sites
        • Sites.FullControl.All

Clique no botão azul "Adicionar permissões" na parte inferior para adicionar as permissões ao seu aplicativo. As "permissões de aplicativo" são aquelas concedidas ao aplicativo ao executar como Somente aplicativo.

concedendo permissões ao aplicativo de anúncios do azure

A etapa final é "conectar" o certificado que criamos anteriormente ao aplicativo. Clique em "Certificados & segredos" na barra de menus à esquerda. Clique no botão "Carregar certificado", selecione o . Arquivo CER que você gerou anteriormente e clique em "Adicionar" para carregá-lo.

Para confirmar se o certificado foi registrado com êxito, clique em "Manifesto" na barra de menus à esquerda. Pesquise a propriedade keyCredentials . Deve ser parecido com:

  "keyCredentials": [
    {
      "customKeyIdentifier": "<$base64CertHash>",
      "endDate": "2021-05-01T00:00:00Z",
      "keyId": "<$guid>",
      "startDate": "2019-05-01T00:00:00Z",
      "type": "AsymmetricX509Cert",
      "usage": "Verify",
      "value": "<$base64Cert>",
      "displayName": "CN=<$name of your cert>"
     }
  ],

Se você vir uma seção um pouco semelhante a essa, o certificado será adicionado com êxito.

Neste exemplo, a permissão de aplicativo Sites.FullControl.All requer o consentimento do administrador em um locatário antes que ele possa ser usado. Para fazer isso, clique em "permissões de API" no menu esquerdo novamente. Na parte inferior, você verá uma seção "Conceder consentimento". Clique no botão "Conceder consentimento do administrador para {{nome da organização}}" e confirme a ação clicando no botão "Sim" que aparece na parte superior.

concedendo permissões de API ao aplicativo de anúncios do Azure

Usando essa entidade com o PowerShell PnP

Se você quiser usar esta entidade somente de aplicativo do AAD com o PnP PowerShell, depois de instalar o módulo PnP PowerShell, você pode se conectar ao seu ambiente do SharePoint Online usando:

Connect-PnPOnline -ClientId <$application client id as copied over from the AAD app registration above> -CertificatePath '<$path to the PFX file generated by the PowerShell script above>' -CertificatePassword (ConvertTo-SecureString -AsPlainText "<$password assigned to the generated certificate pair above>" -Force) -Url https://<$yourtenant>.sharepoint.com -Tenant "<$tenantname>.onmicrosoft.com"

Agora você pode executar operações por meio do PowerShell PnP em seu ambiente do SharePoint Online usando essa confiança somente de aplicativo de certificado.

Observação

O PnP PowerShell é uma solução de software livre com uma comunidade ativa de suporte. Não há nenhuma SLA para o suporte da ferramenta de software livre por parte da Microsoft.

Usando essa entidade em seu aplicativo usando a biblioteca do SharePoint PnP Framework

Em uma primeira etapa, você adiciona o pacote NuGet da biblioteca PnP Framework: https://www.nuget.org/packages/PnP.Framework.

Depois que isso for feito, você poderá usar o constructo de código abaixo:

using PnP.Framework;
using System;

namespace AzureADCertAuth
{
    class Program
    {
        static void Main(string[] args)
        {
            var authManager = new AuthenticationManager("<application id>", "c:\\temp\\mycert.pfx", "<password>", "contoso.onmicrosoft.com");
            using (var cc = authManager.GetContext("https://contoso.sharepoint.com/sites/demo"))
            {
                cc.Load(cc.Web, p => p.Title);
                cc.ExecuteQuery();
                Console.WriteLine(cc.Web.Title);
            };
        }
    }
}

Observação

O PnP Framework é uma solução de código aberto com a comunidade ativa fornecendo suporte para ela. Não há nenhuma SLA para o suporte da ferramenta de software livre por parte da Microsoft.

Usando essa entidade no script do Powershell usando a biblioteca PnP Framework

Ao usar Automação do Azure Runbooks, primeiro adicione o certificado (.pfx) usando a opção Certificados (em Recursos Compartilhados) e use o cmdlet Get-AutomationCertificate para recuperar o certificado a ser usado no script.

Observação

Primeiro, você precisa adicionar o módulo PnP.Framework à conta de automação. Este módulo contém tudo o que é necessário para fazer a chamada de autenticação.

# path to installed modules
$path = "C:\Modules\User\SharePointPnPPowerShellOnline"

# reference to needed assemblies
Add-Type -Path "$path\Microsoft.SharePoint.Client.dll"
Add-Type -Path "$path\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "$path\PnP.Framework.dll"
Add-Type -Path "$path\PnP.Core.dll"
Add-Type -Path "$path\Microsoft.Identity.Client.dll"

# reference to the certificate
$cert = Get-AutomationCertificate -Name 'NameOfCertificate'

# set the variables
$siteUrl = "https://<tenant>.sharepoint.com"
$appId = "<guid of the App>"
$domain = "<tenant>.onmicrosoft.com"
$azureEnv = [PnP.Framework.AzureEnvironment]::Production

try {
    # instantiate the object
    $clientContext = $null
    $authManager = new-object PnP.Framework.AuthenticationManager($appId, $cert, $domain, $null, $azureEnv)

    # configure the object
    $clientContext = $authManager.GetContext($siteUrl)

    # do some stuff
    $clientContext.Load($clientContext.Web)
    $clientContext.ExecuteQuery()
    $clientContext.Web.Title
}
catch {
    # catch error if needed
}
finally {
    $clientContext.Dispose()
}

Usar essa entidade no aplicativo e usar o Azure KeyVault para armazenar o certificado e recuperá-lo usando uma Função do Azure

Adicione uma Identidade Gerenciada à Função do Azure e dê a essa identidade acesso (permissão GET em Segredos) ao KeyVault.

Abaixo há uma chamada ligeiramente diferente para o mesmo método AuthenticationManager em que passamos um certificado real em vez de um caminho para o certificado. Uma função extra é adicionada para recuperar o certificado do KeyVault usando a identidade gerenciada da Função do Azure, essa recuperação é perfeita e transparente, pois a 'mágica' acontece no DefaultAzureCredential.

Este exemplo usa duas bibliotecas para acessar o Key Vault:

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Microsoft.SharePoint.Client;
using System.Security.Cryptography.X509Certificates;

using (var cc = new PnP.Framework.AuthenticationManager(
    "<application id>",
    GetKeyVaultCertificate("kv-spo", "AzureAutomationSPOAccess"),
    "contoso.onmicrosoft.com").GetContext("https://contoso.sharepoint.com/sites/demo"))
{
    cc.Load(cc.Web, p => p.Title);
    cc.ExecuteQuery();
    log.Info("Via PnP, we have site: " + cc.Web.Title);
};

static X509Certificate2 GetKeyVaultCertificate(string keyvaultName, string name)
{
    // Some steps need to be taken to make this work
    // 1. Create a KeyVault and upload the certificate
    // 2. Give the Function App the permission to GET certificates via Access Policies in the KeyVault
    // 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 GetSecret method
    Uri keyVaultUri = new Uri($"https://{keyvaultName}.vault.azure.net/");

    var client = new SecretClient(keyVaultUri, new DefaultAzureCredential());
    KeyVaultSecret secret = client.GetSecret(name);

    return new X509Certificate2(Convert.FromBase64String(secret.Value), string.Empty, X509KeyStorageFlags.MachineKeySet);
}


Usando essa entidade com o Scanner de Modernização Pnp

Agora que você criou o Registro de Aplicativo do Azure Active Directory, prossiga seguindo as etapas aqui para usar essa entidade com a ferramenta.

Perguntas frequentes

Posso usar outros meios além de certificados para realizar o acesso somente ao aplicativo para meu aplicativo Azure AD?

Não, todas as outras opções são bloqueadas pelo SharePoint Online e resultarão em uma mensagem de Acesso Negado.