Configurar o App Service ou a aplicação Azure Functions para iniciar sessão usando um provedor Iniciar sessão com a Apple (Pré-visualização)

Este artigo mostra-lhe como configurar o Serviço de Aplicativos do Azure ou funções do Azure para utilizar o recurso "Início de Sessão com Apple" como fornecedor de autenticação.

Para completar o procedimento deste artigo, deve inscrever-se no programa de programadores da Apple. Para se inscrever no programa de desenvolvedores da Apple, vá para developer.apple.com/programs/enroll.

Atenção

Ativar o Login com a Apple desativa a gestão da funcionalidade de Autenticação e Autorização de Serviços de Aplicações para a sua aplicação através de alguns clientes, como o portal Azure, Azure CLI e Azure PowerShell. A funcionalidade depende de uma nova interface de API, que, durante a visualização preliminar, ainda não está contabilizada em todos os ambientes de gestão.

Criar uma aplicação no portal do programador Apple

Crie um ID de aplicação e um ID de serviço no portal Apple Developer.

  1. No portal do desenvolvedor da Apple, vá para Certificados, Identificadores e Perfis.

  2. Na guia Identificadores, selecione o botão (+).

  3. Na página Registrar um Novo Identificador, escolha IDs do aplicativo e selecione Continuar. Os IDs de aplicação incluem um ou mais ID de Serviço.

    A captura de ecrã mostra a página Registar um Novo Identificador no Portal de Desenvolvedores da Apple, com os IDs das Aplicações destacados.

  4. Na página Registar um ID de App , forneça uma descrição e um ID do pacote.

  5. Na lista de capacidades, selecione Iniciar sessão com a Apple e depois selecione Continuar. Tome nota do Prefixo do ID da Aplicação (ID da Equipa) neste passo. Você precisa dele mais tarde.

    A captura de ecrã mostra a configuração de um novo identificador de aplicação no Portal de Desenvolvedores da Apple.

  6. Reveja as informações de registo da aplicação e selecione Registar.

  7. Novamente, no separador Identificadores, selecione o botão (+).

    Captura de tela mostra a página do Identificador com o ícone de adicionar destacado no Portal de Desenvolvedores da Apple.

  8. Na página Registrar um Novo Identificador, escolha IDs de Serviços e selecione Continuar.

    A captura de ecrã mostra à página Registar um Novo Identificador no Portal de Desenvolvedores da Apple, com os IDs de Serviços destacados.

  9. Na página Registrar uma ID de Serviços, forneça uma descrição e um identificador. Em seguida, selecione Configurar.

    A captura de ecrã mostra uma descrição e um identificador.

    A descrição é o que o utilizador vê no ecrã de consentimento. O identificador é o ID do seu cliente usado na configuração do fornecedor Apple com o seu serviço de aplicação.

  10. No diálogo, defina o ID Primário da Aplicação para o ID da Aplicação que criou anteriormente. Especifique o domínio do seu aplicativo na seção domínio. Para o URL de retorno, utilize o URL <app-url>/.auth/login/apple/callback. Por exemplo, https://contoso.azurewebsites.net/.auth/login/apple/callback. Em seguida, selecione Adicionar e Salvar.

    A captura de ecrã mostra a especificação do domínio e do URL de retorno para o registo.

  11. Revise as informações de registo de serviço e depois selecione Guardar.

Gerar o segredo do cliente

A Apple exige que os programadores de aplicações criem e assinem um JSON Web Token (JWT) como valor secreto do cliente. Para gerar esse segredo, primeiro gere e baixe uma chave privada de curva elíptica do portal do desenvolvedor da Apple. Em seguida, use essa chave para assinar um JWT com um payload específico.

Criar e transferir a chave privada

  1. Na guia Chaves no portal do desenvolvedor da Apple, escolha Criar uma chave ou selecione o botão (+).
  2. Na página Registar uma Nova Chave , dê um nome à chave, selecione Iniciar sessão com a Apple e selecione Configurar.
  3. Na página Configurar Chave, vincule a chave à ID do aplicativo principal que você criou anteriormente e selecione Salvar.
  4. Termine de criar a chave confirmando a informação e selecionando Continuar. Depois analisa a informação e seleciona Registar-se.
  5. Na página Descarregar a Sua Chave, descarregue a chave. Descarrega-se como um .p8 ficheiro (PKCS#8). Usas o conteúdo do ficheiro para assinar o teu JWT secreto de cliente.

Estruturar o segredo do cliente JWT

A Apple exige que o segredo do cliente seja a codificação base64 de um JWT. O JWT decodificado deve ter uma carga útil estruturada como este exemplo:

{
  "alg": "ES256",
  "kid": "URKEYID001",
}.{
  "sub": "com.yourcompany.app1",
  "nbf": 1560203207,
  "exp": 1560289607,
  "iss": "ABC123DEFG",
  "aud": "https://appleid.apple.com"
}.[Signature]
  • sub: O ID do Cliente Apple, também o ID de serviço
  • iss: O ID da sua equipa de programadores Apple
  • aud: A Apple está recebendo o token, então eles são o público
  • exp: Não mais de seis meses após nbf

A versão codificada base64 desta carga útil é a seguinte:

eyJhbGciOiJFUzI1NiIsImtpZCI6IlVSS0VZSUQwMDEifQ.eyJzdWIiOiJjb20ueW91cmNvbXBhbnkuYXBwMSIsIm5iZiI6MTU2MDIwMzIwNywiZXhwIjoxNTYwMjg5NjA3LCJpc3MiOiJBQkMxMjNERUZHIiwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSJ9.ABSXELWuTbgqfrIUz7bLi6nXvkXAz5O8vt0jB2dSHTQTib1x1DSP4__4UrlKI-pdzNg1sgeocolPNTmDKazO8-BHAZCsdeeTNlgFEzBytIpMKFfVEQbEtGRkam5IeclUK7S9oOva4EK4jV4VmgDrr-LGWWO3TaAxAvy3_ZoKohvFFkVG

Nota

A Apple não aceita JWTs secretos de clientes com uma data de expiração superior a seis meses após a data de criação, ou nbf. Precisa de rotacionar a chave secreta do cliente, pelo menos, de seis em seis meses.

Para mais informações sobre como gerar e validar tokens, consulte a documentação para programadores da Apple.

Assine a chave secreta do cliente JWT

Usas o .p8 ficheiro que descarregaste anteriormente para assinar o JWT secreto do cliente. Este ficheiro é um PKCS#8 que contém a chave de assinatura privada em formato PEM. Existem muitas bibliotecas que podem criar e assinar o JWT para você.

Existem diferentes tipos de bibliotecas de código aberto disponíveis on-line para criar e assinar JWTs. Para obter mais informações sobre como gerar JWTs, consulte JSON Web Token (JWT).

Por exemplo, uma forma de gerar o segredo do cliente é importar o pacote NuGet Microsoft.IdentityModel.Tokens e executar o código C# mostrado aqui:

using Microsoft.IdentityModel.Tokens;

public static string GetAppleClientSecret(string teamId, string clientId, string keyId, string p8key)
{
    string audience = "https://appleid.apple.com";

    string issuer = teamId;
    string subject = clientId;
    string kid = keyId;

    IList<Claim> claims = new List<Claim> {
        new Claim ("sub", subject)
    };

    CngKey cngKey = CngKey.Import(Convert.FromBase64String(p8key), CngKeyBlobFormat.Pkcs8PrivateBlob);

    SigningCredentials signingCred = new SigningCredentials(
        new ECDsaSecurityKey(new ECDsaCng(cngKey)),
        SecurityAlgorithms.EcdsaSha256
    );

    JwtSecurityToken token = new JwtSecurityToken(
        issuer,
        audience,
        claims,
        DateTime.Now,
        DateTime.Now.AddDays(180),
        signingCred
    );
    token.Header.Add("kid", kid);
    token.Header.Remove("typ");

    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

    return tokenHandler.WriteToken(token);
}
  • teamId: O seu ID de equipa de programadores Apple
  • clientId: O ID do Cliente Apple, também o ID de serviço
  • p8key: A chave de formato PEM. Pode obter a chave abrindo o .p8 ficheiro num editor de texto e copiando tudo entre -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY----- sem quebras de linha.
  • keyId: O ID da chave baixada

Este token devolvido é o valor secreto do cliente utilizado para configurar o fornecedor Apple.

Importante

O segredo do cliente é uma credencial de segurança importante. Não partilhe este segredo com ninguém nem o distribua numa aplicação cliente.

Adicione o segredo do cliente como uma configuração de aplicativo para o aplicativo, usando um nome de configuração de sua escolha. Anote este nome para mais tarde.

Adicionar informações do provedor ao seu aplicativo

Nota

A configuração necessária está em um novo formato de API, atualmente suportado apenas pela configuração baseada em arquivo (visualização). Tens de seguir os passos aqui para usar um ficheiro assim.

Esta secção descreve a atualização da configuração para incluir o seu novo IDP. Segue-se um exemplo de configuração.

  1. No identityProviders objeto, adiciona um apple objeto se ainda não existir um.

  2. Atribua um objeto a essa chave com um registration objeto dentro dela e, opcionalmente, um login objeto:

    "apple" : {
       "registration" : {
            "clientId": "<client ID>",
            "clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_CLIENT_SECRET" 
        },
       "login": {
             "scopes": []
       }
    }
    
  3. No registration objeto, defina o clientId para o ID do cliente que recolheu.

  4. No registration objeto, define clientSecretSettingName para o nome da definição da aplicação onde guardaste o segredo do cliente.

  5. No login objeto, pode escolher definir o scopes array para incluir uma lista de escopos usados ao autenticar com a Apple, como nome e email. Se os escopos estiverem configurados, são explicitamente solicitados no ecrã de consentimento quando os utilizadores iniciam sessão pela primeira vez.

Depois de definir esta configuração, está pronto para usar o seu fornecedor Apple para autenticação na sua aplicação.

Uma configuração completa pode assemelhar-se ao seguinte exemplo, onde a definição de APPLE_GENERATED_CLIENT_SECRET aponta para uma configuração de aplicação que contém um JWT gerado:

{
    "platform": {
        "enabled": true
    },
    "globalValidation": {
        "redirectToProvider": "apple",
        "unauthenticatedClientAction": "RedirectToLoginPage"
    },
    "identityProviders": {
        "apple": {
            "registration": {
                "clientId": "com.contoso.example.client",
                "clientSecretSettingName": "APPLE_GENERATED_CLIENT_SECRET"
            },
            "login": {
                "scopes": []
            }
        }
    },
    "login": {
        "tokenStore": {
            "enabled": true
        }
    }     
}