Lidando com a autenticação

Tipos de autenticação

Uma extensão pode dar suporte a um ou mais tipos de Autenticação. Cada tipo de autenticação é um tipo diferente de credencial. A interface do usuário de autenticação exibida para usuários finais no Power Query é controlada pelo tipo de credenciais compatíveis com uma extensão.

A lista de tipos de autenticação com suporte é definida como parte da definição do Tipo de Fonte de Dados de uma extensão. Cada valor de Autenticação é um registro com campos específicos. A tabela a seguir lista os campos esperados para cada tipo. Todos os campos são obrigatórios, a menos que marcado de outra forma.

Tipo de autenticação Campo Descrição
Anônima O tipo de autenticação Anônimo (também chamado Implicit) não tem qualquer tipo de campo.
OAuth StartLogin Função que fornece a URL e as informações de estado para iniciar um fluxo OAuth.

Vá para a seção Implementando um fluxo do OAuth.
FinishLogin Função que extrai o access_token e outras propriedades relacionadas ao fluxo OAuth.
Atualizar (opcional) Função que recupera um novo token de acesso de um token de atualização.
Logout (opcional) Função que invalida o token de acesso atual do usuário.
Etiqueta (opcional) Um valor de texto que permite substituir o rótulo padrão para este AuthenticationKind.
Aad AuthorizationUri Valor text ou função unária que retorna o ponto de extremidade da autorização do Microsoft Entra ID (exemplo: "https://login.microsoftonline.com/common/oauth2/authorize").

Vá para a seção Autenticação do Microsoft Entra ID.
Recurso Valor text ou função unária que retorna o valor do recurso do Microsoft Entra ID para seu serviço.
Escopo (opcional)text valor ou função unária que retorna a lista de escopos a serem solicitados como parte do fluxo de autenticação. Vários valores de escopo devem ser separados por um espaço. O valor do escopo deve ser o nome do escopo, sem um URI de ID do Aplicativo (exemplo: Data.Read). Quando não fornecido, o escopo user_impersonation é solicitado.
UsernamePassword userNameLabel (opcional) Um valor de texto para substituir o rótulo padrão para a caixa de texto Nome de Usuário na interface do usuário de credenciais.
PasswordLabel (opcional) Um valor de texto para substituir o rótulo padrão para a caixa de texto Senha na interface do usuário de credenciais.
Etiqueta (opcional) Um valor de texto que permite substituir o rótulo padrão para este AuthenticationKind.
Windows userNameLabel (opcional) Um valor de texto para substituir o rótulo padrão para a caixa de texto Nome de Usuário na interface do usuário de credenciais.
PasswordLabel (opcional) Um valor de texto para substituir o rótulo padrão para a caixa de texto Senha na interface do usuário de credenciais.
Etiqueta (opcional) Um valor de texto que permite substituir o rótulo padrão para este AuthenticationKind.
Chave KeyLabel (opcional) Um valor de texto para substituir o rótulo padrão para a caixa de texto Chave de API na interface do usuário de credenciais.
Etiqueta (opcional) Um valor de texto que permite substituir o rótulo padrão para este AuthenticationKind.

O exemplo a seguir mostra o registro de autenticação de um conector que oferece suporte a credenciais do OAuth, Key, Windows, Basic (nome de usuário e senha) e Anônimo.

Exemplo:

Authentication = [
    OAuth = [
        StartLogin = StartLogin,
        FinishLogin = FinishLogin,
        Refresh = Refresh,
        Logout = Logout
    ],
    Key = [],
    UsernamePassword = [],
    Windows = [],
    Anonymous = []
]

Acessar as credenciais atuais

As credenciais atuais podem ser recuperadas usando a função Extension.CurrentCredential.

As funções de fonte de dados do M que foram habilitadas para extensibilidade herdam automaticamente o escopo de credenciais da extensão. Na maioria dos casos, você não precisa acessar explicitamente as credenciais atuais, mas há exceções, como:

  • Passagem da credencial em um cabeçalho personalizado ou parâmetro de cadeia de caracteres de consulta (como quando você está usando o tipo de autenticação de Chave de API).
  • Definir propriedades da cadeia de conexão para extensões ODBC ou ADO.NET.
  • Verificar propriedades personalizadas em um token do OAuth.
  • Usar as credenciais como parte de um fluxo do OAuth v1.

A função Extension.CurrentCredential retorna um objeto de registro. Os campos que ele contém são específicos do tipo de autenticação. A tabela a seguir contém detalhes.

Campo Descrição Usado Por
AuthenticationKind Contém o nome do tipo de autenticação atribuído a essa credencial (UsernamePassword, OAuth e assim por diante). Tudo
Nome de Usuário Valor de nome de usuário UsernamePassword, Windows
Senha Valor da senha. Normalmente usado com UsernamePassword, mas também é definido como Key. Chave, UsernamePassword, Windows
access_token Valor do token de acesso OAuth. OAuth
Propriedades Um registro que contém outras propriedades personalizadas para uma credencial específica. Normalmente usado com o OAuth para armazenar outras propriedades (como o refresh_token) retornado com o access_token durante o fluxo de autenticação. OAuth
Chave O valor da Chave de API. Observe que o valor da chave também está disponível no campo Senha. Por padrão, o mecanismo de mashup insere essa chave em um cabeçalho Autorização como se esse valor fosse uma senha de autenticação básica (sem nome de usuário). Se esse tipo de comportamento não for o desejado, você deverá especificar a opção ManualCredentials = true no registro de opções. Chave
EncryptConnection Um valor lógico que determinou se é necessário uma conexão criptografada com a fonte de dados. Esse valor está disponível para todos os tipos de autenticação, mas só é definido se EncryptConnection for especificado na definição de fonte de dados. Tudo

O exemplo de código a seguir acessa a credencial atual de uma chave de API e a usa para preencher um cabeçalho personalizado (x-APIKey).

Exemplo:

MyConnector.Raw = (_url as text) as binary =>
let
    apiKey = Extension.CurrentCredential()[Key],
    headers = [

        #"x-APIKey" = apiKey,
        Accept = "application/vnd.api+json",
        #"Content-Type" = "application/json"
    ],
    request = Web.Contents(_url, [ Headers = headers, ManualCredentials = true ])
in
    request

Implementando um fluxo do OAuth

O tipo de autenticação OAuth permite que uma extensão implemente a lógica personalizada para o serviço. Para fazer isso, uma extensão fornece funções para StartLogin(retornando o URI de autorização para iniciar o fluxo do OAuth) e FinishLogin (trocando o código de autorização por um token de acesso). As extensões também podem implementar Refresh (trocando um token de atualização por um novo token de acesso) e Logout (expirando os tokens de atualização e acesso atuais).

Observação

As extensões do Power Query são avaliadas em aplicativos em execução em computadores cliente. Os Conectores de Dados não devem usar segredos confidenciais em seus fluxos OAuth, pois os usuários podem inspecionar a extensão ou o tráfego de rede para saber o segredo. Vá para Troca de Chave por Código pelo RFC de clientes públicos do OAuth (também conhecido como PKCE) para obter mais detalhes sobre como fornecer fluxos que não dependem de segredos compartilhados. Uma implementação de exemplo desse fluxo pode ser encontrada em nosso site do GitHub.

Há dois conjuntos de assinaturas de função do OAuth: a assinatura original que contém um número mínimo de parâmetros e uma assinatura avançada que aceita mais parâmetros. A maioria dos fluxos OAuth pode ser implementada usando as assinaturas originais. Você também pode misturar e combinar os tipos de assinatura em sua implementação. As chamadas de função são correspondências com base no número de parâmetros (e seus tipos). Os nomes dos parâmetros não são levados em consideração.

Acesse a amostra do GitHub para mais detalhes.

Assinaturas do OAuth originais

StartLogin = (dataSourcePath, state, display) => ...;

FinishLogin = (context, callbackUri, state) => ...;

Refresh = (dataSourcePath, refreshToken) =>  ...;

Logout = (accessToken) => ...;

Assinaturas do OAuth avançadas

Notas sobre as assinaturas avançadas:

  • Todas as assinaturas aceitam um valor de registroclientApplication, que é reservado para uso futuro.
  • Todas as assinaturas aceitam uma dataSourcePath (também conhecida como resourceUrl na maioria dos exemplos).
  • A função Refresh aceita um parâmetro oldCredential, que é o record anterior retornado por sua função FinishLogin (ou chamada anterior para Refresh).
StartLogin = (clientApplication, dataSourcePath, state, display) => ...;

FinishLogin = (clientApplication, dataSourcePath, context, callbackUri, state) => ...;

Refresh = (clientApplication, dataSourcePath, oldCredential) =>  ...;

Logout = (clientApplication, dataSourcePath, accessToken) => ...;

Autenticação do Microsoft Entra ID

A variante de autenticação Aad é uma versão especializada do OAuth para o Microsoft Entra ID. Ele usa o mesmo cliente do Microsoft Entra ID que os conectores do Power Query internos compatíveis com a autenticação da conta institucional. Mais informações podem ser encontradas no guia de início rápido Configurar o Microsoft Entra para um conector personalizado.

Observação

Se você implementar seu próprio fluxo OAuth para o Microsoft Entra ID, os usuários com o Acesso Condicional habilitado para seus locatários poderão encontrar problemas ao atualizar usando o serviço do Power BI. Isso não afetará a atualização baseada em gateway, mas afetará um conector certificado que dá suporte à atualização do serviço do Power BI. Os usuários poderão ter um problema decorrente do conector usando um aplicativo cliente público ao configurar credenciais baseadas na Web por meio do serviço do Power BI. Dessa forma, o token de acesso gerado por esse fluxo será usado em um computador diferente (ou seja, o serviço do Power BI em um data center do Azure, não na rede da empresa) do que aquele usado para autenticar originalmente (ou seja, o computador do usuário que configura as credenciais da fonte de dados na rede da empresa). O tipo interno Aad resolve esse problema usando um cliente do Microsoft Entra ID diferente ao configurar credenciais no serviço do Power BI. Essa opção não estará disponível para conectores que usam o tipo de autenticação OAuth.

A maioria dos conectores precisa fornecer valores para os campos AuthorizationUri e Resource. Ambos os campos podem ser valores text ou uma única função de argumento que retorna um text value.

AuthorizationUri = "https://login.microsoftonline.com/common/oauth2/authorize"
AuthorizationUri = (dataSourcePath) => FunctionThatDeterminesAadEndpointFromDataSourcePath(dataSourcePath)
Resource = "77256ee0-fe79-11ea-adc1-0242ac120002"   // Microsoft Entra ID resource value for your service - Guid or URL
Resource = (dataSourcePath) => FunctionThatDeterminesResourceFromDataSourcePath(dataSourcePath)

Os conectores que usam um identificador baseado em Uri não precisam fornecer um Resource valor. Por padrão, o valor é igual ao caminho raiz do parâmetro do Uri do conector. Se o recurso do Microsoft Entra ID da fonte de dados for diferente do valor do domínio (por exemplo, ele usa um GUID), será necessário fornecer um valor Resource.

Exemplos do tipo de autenticação do AAD

No caso a seguir, a fonte de dados dá suporte ao Microsoft Entra ID na nuvem global usando o locatário comum (sem suporte B2B do Azure). A solicitação do escopo .default retorna um token com todos os escopos autorizados anteriormente para o ID do aplicativo cliente do Power Query.

Authentication = [
    Aad = [
        AuthorizationUri = "https://login.microsoftonline.com/common/oauth2/authorize",
        Resource = "77256ee0-fe79-11ea-adc1-0242ac120002", // Entra Application ID URI or app guid
        Scope = ".default"
    ]
]

No caso a seguir, a fonte de dados oferece suporte à descoberta de locatário com base no OpenID Connect (OIDC) ou protocolo semelhante. Essa capacidade permite que o conector determine o ponto de extremidade correto do Microsoft Entra ID a ser usado com base em um ou mais parâmetros no caminho da fonte de dados. Essa abordagem de descoberta dinâmica permite que o conector dê suporte ao Azure B2B.


// Implement this function to retrieve or calculate the service URL based on the data source path parameters
GetServiceRootFromDataSourcePath = (dataSourcePath) as text => ...;

GetAuthorizationUrlFromWwwAuthenticate = (url as text) as text =>
    let
        // Sending an unauthenticated request to the service returns
        // a 302 status with WWW-Authenticate header in the response. The value will
        // contain the correct authorization_uri.
        // 
        // Example:
        // Bearer authorization_uri="https://login.microsoftonline.com/{tenant_guid}/oauth2/authorize"
        responseCodes = {302, 401},
        endpointResponse = Web.Contents(url, [
            ManualCredentials = true,
            ManualStatusHandling = responseCodes
        ])
    in
        if (List.Contains(responseCodes, Value.Metadata(endpointResponse)[Response.Status]?)) then
            let
                headers = Record.FieldOrDefault(Value.Metadata(endpointResponse), "Headers", []),
                wwwAuthenticate = Record.FieldOrDefault(headers, "WWW-Authenticate", ""),
                split = Text.Split(Text.Trim(wwwAuthenticate), " "),
                authorizationUri = List.First(List.Select(split, each Text.Contains(_, "authorization_uri=")), null)
            in
                if (authorizationUri <> null) then
                    // Trim and replace the double quotes inserted before the url
                    Text.Replace(Text.Trim(Text.Trim(Text.AfterDelimiter(authorizationUri, "=")), ","), """", "")
                else
                    error Error.Record("DataSource.Error", "Unexpected WWW-Authenticate header format or value during authentication.", [
                        #"WWW-Authenticate" = wwwAuthenticate
                    ])
        else
            error Error.Unexpected("Unexpected response from server during authentication.");

<... snip ...>

Authentication = [
    Aad = [
        AuthorizationUri = (dataSourcePath) =>
            GetAuthorizationUrlFromWwwAuthenticate(
                GetServiceRootFromDataSourcePath(dataSourcePath)
            ),
        Resource = "https://myAadResourceValue.com", // Microsoft Entra ID resource value for your service - Guid or URL
        Scope = ".default"
    ]
]

Outros tipos de autenticação

Para obter informações sobre outros tipos de autenticação não abordados neste artigo, como logon único baseado em Kerberos, acesse o artigo de funcionalidade de conector adicional para saber mais.