Configurare l'servizio app o l'app Funzioni di Azure per accedere usando un provider Apple (anteprima)

Questo articolo illustra come configurare Servizio app di Azure o Funzioni di Azure per usare l'accesso con Apple come provider di autenticazione.

Per completare la procedura in questo articolo, è necessario aver registrato il programma per sviluppatori Apple. Per iscriversi al programma per sviluppatori Apple, passare a developer.apple.com/programs/enroll.

Attenzione

L'abilitazione dell'accesso con Apple disabilita la gestione della funzionalità autenticazione/autorizzazione di servizio app per l'applicazione tramite alcuni client, ad esempio l'portale di Azure, l'interfaccia della riga di comando di Azure e Azure PowerShell. La funzionalità si basa su una nuova superficie API che, durante l'anteprima, non è ancora usata in tutte le esperienze di gestione.

Creare un'applicazione nel portale per sviluppatori Apple

È necessario creare un ID app e un ID servizio nel portale per sviluppatori Apple.

  1. Nel portale per sviluppatori Apple passare a Certificati, Identificatori, & Profili.
  2. Nella scheda Identificatori selezionare il pulsante (+).
  3. Nella pagina Registra un nuovo identificatore scegliere ID app e selezionare Continua. Gli ID app includono uno o più ID servizio. Registrazione di un nuovo identificatore di app nel portale per sviluppatori Apple
  4. Nella pagina Registra un ID app specificare una descrizione e un ID bundle e selezionare Accedi con Apple nell'elenco delle funzionalità. Selezionare quindi Continua. Prendere nota del prefisso ID app (ID team) da questo passaggio, sarà necessario in un secondo momento. Configurazione di un nuovo identificatore di app nel portale per sviluppatori Apple
  5. Esaminare le informazioni di registrazione dell'app e selezionare Registra.
  6. Anche in questo caso, nella scheda Identificatori selezionare il pulsante (+). Creazione di un nuovo identificatore di servizio nel portale per sviluppatori Apple
  7. Nella pagina Registra un nuovo identificatore scegliere ID servizi e selezionare Continua. Registrazione di un nuovo identificatore di servizio nel portale per sviluppatori Apple
  8. Nella pagina Registra un ID servizi specificare una descrizione e un identificatore. La descrizione è ciò che verrà visualizzato all'utente nella schermata di consenso. L'identificatore sarà l'ID client usato per configurare il provider Apple con il servizio app. Selezionare quindi Configura. Specificare una descrizione e un identificatore
  9. Nella finestra popup impostare l'ID app primario sull'ID app creato in precedenza. Specificare il dominio dell'applicazione nella sezione dominio. Per l'URL restituito, usare l'URL <app-url>/.auth/login/apple/callback. Ad esempio, https://contoso.azurewebsites.net/.auth/login/apple/callback. Selezionare Quindi Aggiungi e Salva. Specifica del dominio e dell'URL restituito per la registrazione
  10. Esaminare le informazioni di registrazione del servizio e selezionare Salva.

Generare il segreto client

Apple richiede agli sviluppatori di app di creare e firmare un token JWT come valore del segreto client. Per generare questo segreto, generare e scaricare prima una chiave privata curva ellittica dal portale di Apple Developer. Usare quindi tale chiave per firmare un JWT con un payload specifico.

Creare e scaricare la chiave privata

  1. Nella scheda Chiavi nel portale per sviluppatori Apple scegliere Crea una chiave o selezionare il pulsante (+).
  2. Nella pagina Registra una nuova chiave specificare il nome della chiave, selezionare la casella accanto a Accedi con Apple e selezionare Configura.
  3. Nella pagina Configura chiave collegare la chiave all'ID dell'app primaria creato in precedenza e selezionare Salva.
  4. Completare la creazione della chiave confermando le informazioni e selezionando Continua e quindi esaminando le informazioni e selezionando Registra.
  5. Nella pagina Scarica chiave scaricare la chiave. Verrà scaricato come .p8 file PKCS#8: si userà il contenuto del file per firmare il segreto client JWT.

Struttura del segreto client JWT

Apple richiede che il segreto client sia la codifica base64 di un token JWT. Il token JWT decodificato deve avere un payload strutturato come questo esempio:

{
  "alg": "ES256",
  "kid": "URKEYID001",
}.{
  "sub": "com.yourcompany.app1",
  "nbf": 1560203207,
  "exp": 1560289607,
  "iss": "ABC123DEFG",
  "aud": "https://appleid.apple.com"
}.[Signature]
  • sub: ID client Apple (anche l'ID servizio)
  • iss: ID team per sviluppatori Apple
  • aud: Apple riceve il token, quindi sono il pubblico
  • exp: Non più di sei mesi dopo nbf

La versione con codifica base64 del payload precedente è simile alla seguente: eyJhbGciOiJFUzI1NiIsImtpZCI6IlVSS0VZSUQwMDEifQ.eyJzdWIiOiJjb20ueW91cmNvbXBhbnkuYXBwMSIsIm5iZiI6MTU2MDIwMzIwNywiZXhwIjoxNTYwMjg5NjA3LCJpc3MiOiJBQkMxMjNERUZHIiwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSJ9.ABSXELWuTbgqfrIUz7bLi6nXvkXAz5O8vt0jB2dSHTQTib1x1DSP4__4UrlKI-pdzNg1sgeocolPNTmDKazO8-BHAZCsdeeTNlgFEzBytIpMKFfVEQbEtGRkam5IeclUK7S9oOva4EK4jV4VmgDrr-LGWWO3TaAxAvy3_ZoKohvFFkVG

Nota: Apple non accetta JWT del segreto client con una data di scadenza superiore a sei mesi dopo la data di creazione (o nbf). Ciò significa che sarà necessario ruotare il segreto client, almeno ogni sei mesi.

Altre informazioni sulla generazione e la convalida dei token sono disponibili nella documentazione per sviluppatori di Apple.

Firmare il segreto client JWT

Si userà il .p8 file scaricato in precedenza per firmare il segreto client JWT. Questo file è un file PCKS#8 che contiene la chiave di firma privata in formato PEM. Esistono molte librerie che possono creare e firmare il JWT per l'utente.

Esistono diversi tipi di librerie open source disponibili online per la creazione e la firma di token JWT. Per altre informazioni sulla generazione di token JWT, vedere Token Web JSON (JWT). Ad esempio, un modo per generare il segreto client consiste nell'importare la Microsoft. Pacchetto NuGet IdentityModel.Tokens ed esecuzione di una piccola quantità di codice C# illustrato di seguito.

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: ID team per sviluppatori Apple
  • clientId: ID client Apple (anche l'ID servizio)
  • p8key: chiave di formato PEM: è possibile ottenere la chiave aprendo il .p8 file in un editor di testo e copiando tutto tra -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY----- senza interruzioni di riga
  • keyId: ID della chiave scaricata

Questo token restituito è il valore del segreto client che verrà usato per configurare il provider Apple.

Importante

Il segreto client è un'importante credenziale di sicurezza. Non condividere questo valore con altri e non distribuirlo all'interno di un'applicazione client.

Aggiungere il segreto client come impostazione dell'applicazione per l'app usando un nome di impostazione desiderato. Prendere nota di questo nome per un secondo momento.

Aggiungere informazioni sul provider all'applicazione

Nota

La configurazione necessaria è in un nuovo formato API, attualmente supportato solo dalla configurazione basata su file (anteprima). Sarà necessario seguire la procedura seguente usando un file di questo tipo.

Questa sezione illustra come aggiornare la configurazione per includere il nuovo IDP. Di seguito è riportato un esempio di configurazione.

  1. All'interno dell'oggetto identityProviders aggiungere un apple oggetto se non esiste già.

  2. Assegnare un oggetto a tale chiave con un registration oggetto all'interno di esso e facoltativamente un login oggetto:

    "apple" : {
       "registration" : {
            "clientId": "<client ID>",
            "clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_CLIENT_SECRET" 
        },
       "login": {
             "scopes": []
       }
    }
    

    a. All'interno dell'oggetto impostare l'oggetto sull'ID registrationclientId client raccolto.

    b. registration All'interno dell'oggetto impostare clientSecretSettingName sul nome dell'impostazione dell'applicazione in cui è stato archiviato il segreto client.

    c. All'interno dell'oggetto login è possibile scegliere di impostare la matrice per includere un elenco di ambiti usati durante l'autenticazione scopes con Apple, ad esempio "name" e "email". Se gli ambiti sono configurati, verranno richiesti in modo esplicito nella schermata di consenso quando gli utenti accedono per la prima volta.

Dopo aver impostato questa configurazione, è possibile usare il provider Apple per l'autenticazione nell'app.

Una configurazione completa potrebbe essere simile all'esempio seguente( in cui l'impostazione APPLE_GENERATED_CLIENT_SECRET punta a un'impostazione dell'applicazione contenente un JWT generato):

{
    "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
        }
    }     
}

Passaggi successivi