CDS – Aposentadoria da autenticação Office365 está chegando, é hora de avaliar outras opções (OAuth+Application User)


Olá pessoal,

Em fevereiro deste ano (2020), foi anunciado que a autenticação Office365 (AuthType=Office365) que tanto utilizamos para criar conexões com o CDS será aposentada (maiores detalhes aqui). Assim é hora de nos prepararmos para utilizar outras formas de conexão, este post será dedicado a uma delas, a OAuth!

Com esta aposentaria, a forma de conexão que automaticamente ocupará o espaço é a OAuth (AuthType=OAuth)! OAuth não é algo novo, é um padrão de autenticação multi plataforma já amplamente utilizado no mercado onde conseguimos implementar autenticação de dois fatores (2FA). Seu próprio design necessita de um provedor já autorizado, no CDS precisamos cadastramos este provedor no Azure Active Directory (AAD), que através de uma conta Microsoft (application user) utiliza o Azure Active Directory Authentication Libraries (ADAL). Muitas letrinhas e abreviações?! Calma! Iremos aos detalhes logo a seguir!

Um pouco de contexto…

Talvez para você esteja bem claro que quando falamos de conexão com o CDS, este cenário só existirá quando outra aplicação precisa consumir a WebApi do CDS. Alguns exemplos seriam: uma console application ou um aplicação externa (Microsoft ou não).

Para casos como plugins e workflows customizados o contexto de execução já nos envia uma conexão com o CDS de forma totalmente transparente. Assim, tenha isso em mente para o uso adequado deste post 😉

O que este post contém?

  • Como criar e configurar uma Aplicação no Azure para gerar um AppId
  • Criar um novo usuário no Azure (AAD) e vinculá-lo no Dynamics 365 CE/PowerApps Model-driven
  • Exemplo prático de como fazer a conexão com o OAuth em C#

Antes de começarmos, meu 1 centavo de opinião/ajuda…

Devido a connection string de conexão ao CDS possibilitar que simplemente troquemos o tipo de conexão de Office365 para OAuth, desta forma mantemos a necessidade de informar usuário e senha (user/password). Veja a mudança que pode ser feita:

AuthType=OAuth; Username={username}; Password={password}; Url=https://{org}.{region}.dynamics.com/; AppId={appId}; RedirectUri=app://{redirectUrl}; LoginPrompt=Never

Acredito que alguns de nós tenhamos feito apenas a mudança acima, sim ainda será necessário criar uma aplicação no Azure para gerarmos um AppId, mas desta forma, não temos que nos preocupar com mais nada (veja exemplo). Porém, agora que gostaria que você ponderasse, veja onde eu acho que você precisa considerar:

  • Em 99% dos casos onde precisamos nos conectar ao CDS de forma externa, ou seja, server to server (S2S), o usuário que iremos utilizar é uma conta de serviços, correto? Assim, nada melhor que criar Application user para isso. Aqui que vem o porque de optar OAuth e Application user:
    • Desde a introdução do limite de chamadas a API do CDS, adivinhe que é o tipo de usuário que mais pode fazer chamadas à API?! Sim application user, no pior cenário de todos poderá fazer 5 mil chamadas à mais do que um usuário normal. No melhor cenário são 100.000 chamadas por dia! 5 vezes mais do que um usuário normal!
  • A segurança é algo que também precisa ser considerado, utilizando App User não precisamos armazenar em nenhuma aplicação o usuário e senha, nós nem ao menos precisaremos “dizer” ao CDS o usuário que estamos utilizando para criar a conexão o AAD faz isso para nós!

Bom, com o que disse acima dito, vamos ao que interessa!

Como criar e configurar uma Aplicação no Azure para gerar um AppId

As configurações precisam ser realizadas no Portal Azure, assim faça a autenticação e em seguida pesquise por Azure Active Directory:

 

Clique em App Registrations e depois New Registration. Informe o nome de sua aplicação e clique em Register:

 

Pronto sua aplicação foi criada, assim temos o appId que precisamos para criar a conexão. Copie os ids de Application (client) ID e Directory (tenant) ID em algum que você possa acessar mais tarde.

 

Agora é hora de darmos as devidas permissões para a nossa aplicação. No menu lateral clique em API Permissions e depois clique em Add a new Permission:

 

Selecione a opção user_impersonation e clique em Add Permission:

Permissão criada, agora temos que dar o consentimento para a aplicação ter controle de administrador sobre o Dynamics 365/CDS. Para isso clique Grant admin consent for “SUA ORGANIZACAO”:

 

A última etapa é tornar a aplicação pública. No menu lateral clique em Authentication e selecione Sim (Yes) no switch que concede o acesso público à aplicação (não se esqueça de salvar!):

 

Aplicação habilitada, é hora de criarmos uma senha para a aplicação, no caso um Segredo (secret). No menu lateral clique em “Certificates & secrets“, depois em New client secret e criei seu secret (automaticamente será gerado um código, copie-o em um local para que você possa utilizar futuramente):

 

Bom, tudo que era referente a aplicação está pronto. agora precisamos criar um novo usuário no AAD e no Dynamics 365 CE/PoweApp Model-driven.

Criar um novo usuário no Azure (AAD) e vinculá-lo no Dynamics 365 CE/PowerApps Model-driven

Ainda no portal Azure, pesquise por “User” e depois clique em New user:

Defina o nome e email do novo usuário, e nada mais, nem mesmo a senha é algo que iremos precisar, só precisamos de um usuário mesmo!

Agora abra sua organização de Dynamics 365 CE/PowerApps Model-driven, em Configurações Avançadas > Segurança > Usuários. Troque a visualização para Application Users e depois clique em New:

Comece preenchendo o email, pois ao informa-lo corretamente a maioria dos campos será automaticamente preenchida. Depois informe sua Application ID, a mesma que criou no Azure:

*** Como todo usuário, é preciso um direito de acesso (security role) para que o acesso ao CDS seja concedido, é altamente recomendável que seja criado um novo registro, pois a ideia de um application user é de apenas acessar o que lhe é permitido. Assim irei deixar esta etapa ao seu critério! ***

Usuário criado e com seu direito de acesso associado é hora de fazermos um teste de conexão!

 

Exemplo prático de como fazer a conexão com o OAuth em C#

Fiz uma console application bem, mas bem simples, com apenas o que precisamos e para mostrar a ideia na prática. Precisamos de duas bibliotecas do NuGet uma para o Acive Directory (Microsoft.IdentityModel.Clients.ActiveDirectory) e a do Dynamics (Microsoft.CrmSdk.CoreAssemblies).

Em relação às variáveis de seu ambiente, precisamos informar a URL de sua organização, application, secret e tenant Ids. Vejam que não temos nenhum usuário ou password!

O exemplo irá retornar o código do usuário que está requisitando a informação ao CDS, neste caso o Id de nosso application user, pois estou requisitando um WhoAmI.

Por usarmos OAuth para fazer a autenticação, o resultado na verdade não é uma abertura de conexão e sim um token como resposta positiva da autenticação. Com o token é que criamos nossa conexão, assim, a existência do token é a prova de que a conexão está permitida/habilitada. Este diagrama ajuda a entender o que acontece no background:

Mais informações aqui!

Por útlimo uma menção ao método GetServiceUrl, precisamos informar qual o versão do Sdk nossa organização está utilizando.

Vejam o código abaixo:

using Microsoft.Crm.Sdk.Messages;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.WebServiceClient;
using System;

namespace TMC.OAuthAndApplicationUserDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string serviceUrl = "https://ORG.crmREGION.dynamics.com";
            string clientAppId = "CLIENT_APP_ID";
            string clientSecretId = "CLIENT_SECRET_ID";
            string tenantId = "TENANT_ID";
            string authority = $"https://login.microsoftonline.com/{tenantId}";

            try
            {
                AuthenticationContext authContext = new AuthenticationContext(authority);
                ClientCredential credential = new ClientCredential(clientAppId, clientSecretId);

                AuthenticationResult result = authContext.AcquireTokenAsync(serviceUrl, credential).Result;

                using (var proxy = new OrganizationWebProxyClient(GetServiceUrl(serviceUrl), false))
                {
                    proxy.HeaderToken = result.AccessToken;

                    OrganizationRequest request = new OrganizationRequest()
                    {
                        RequestName = "WhoAmI"
                    };

                    WhoAmIResponse response = proxy.Execute(new WhoAmIRequest()) as WhoAmIResponse;
                    Console.WriteLine(response.UserId);
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"Error Code: {ex.InnerException.HResult}\nMessage: {ex.InnerException.Message}\nStackTrace: {ex.InnerException.StackTrace}");
            }

            Console.WriteLine("Press any key to exit");
            Console.ReadLine();
        }

        static private Uri GetServiceUrl(string organizationUrl)
        {
            return new Uri(organizationUrl + @"/xrmservices/2011/organization.svc/web?SdkClientVersion=9.1");
        }
    }
}

Agora o resultado ao executarmos esta console app:

Baixe todo o código no meu GitHub!

Bom é isso, espero que o post lhe ajude!

Abaixo os links que utilizei para criar este post:

https://docs.microsoft.com/en-us/power-platform/important-changes-coming#deprecation-of-office365-authentication-type-and-organizationserviceproxy-class-for-connecting-to-common-data-service

https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/authenticate-office365-deprecation

https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/authenticate-oauth

https://docs.microsoft.com/en-us/power-platform/admin/api-request-limits-allocations

https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code

 

[]’s,

Tiago

Deixe um comentário

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.