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

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

Per completare la procedura descritta in questo articolo, è necessario essere registrati nel 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 disabiliterà la gestione della funzionalità di autenticazione/autorizzazione di servizio app per l'applicazione tramite alcuni client, ad esempio portale di Azure, 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 considerato in tutte le esperienze di gestione.

Creare un'applicazione nel portale Apple Developer

È necessario creare un ID app e un ID servizio nel portale apple developer.

  1. Nel portale Apple Developer passare a Certificati, Identificatori e 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. Registering a new app identifier in the Apple Developer Portal
  4. Nella pagina Registra un ID app specificare una descrizione e un ID bundle e selezionare Accedi con Apple nell'elenco delle funzionalità. Selezionare Continua. Prendere nota del prefisso ID app (ID team) di questo passaggio, che sarà necessario in un secondo momento. Configuring a new app identifier in the Apple Developer Portal
  5. Esaminare le informazioni di registrazione dell'app e selezionare Registra.
  6. Anche in questo caso, nella scheda Identificatori selezionare il pulsante (+). Creating a new service identifier in the Apple Developer Portal
  7. Nella pagina Registra un nuovo identificatore scegliere ID servizi e selezionare Continua. Registering a new service identifier in the Apple Developer Portal
  8. Nella pagina Registra un ID di 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. Providing a description and an identifier
  9. Nella finestra popup impostare l'ID app primaria 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. Specifying the domain and return URL for the registration
  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 a curva ellittica dal portale Apple Developer. Usare quindi tale chiave per firmare un token JWT con un payload specifico.

Creare e scaricare la chiave privata

  1. Nella scheda Chiavi del portale Apple Developer scegliere Crea una chiave o selezionare il pulsante (+).
  2. Nella pagina Registra una nuova chiave assegnare un nome alla chiave, selezionare la casella accanto a Accedi con Apple e selezionare Configura.
  3. Nella pagina Configura chiave collegare la chiave all'ID app primario 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 la chiave scaricare la chiave. Verrà scaricato come .p8 file (PKCS#8): si userà il contenuto del file per firmare il token JWT del segreto client.

Strutturare il token JWT del segreto client

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

{
  "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 del 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 segreti client con una data di scadenza superiore a sei mesi dopo la data di creazione (o nbf). Ciò significa che è 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 token JWT del segreto client

Si userà il .p8 file scaricato in precedenza per firmare il token JWT del segreto client. Questo file è un file PCKS#8 che contiene la chiave di firma privata in formato PEM. Sono disponibili molte librerie che possono creare e firmare automaticamente il token JWT.

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 il pacchetto NuGet Microsoft.IdentityModel.Tokens ed eseguire 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 del 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 di propria scelta. 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).The required configuration is in a new API format, currently only supported by file-based configuration (preview). Sarà necessario seguire i passaggi seguenti usando un file di questo tipo.

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

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

  2. Assegnare un oggetto a tale chiave con un registration oggetto al suo interno 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 registrationclientId sull'ID client raccolto.

    b. All'interno dell'oggetto registration 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 scopes matrice in modo da includere un elenco di ambiti usati per l'autenticazione 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(dove l'impostazione APPLE_GENERATED_CLIENT_edizione Standard CRET punta a un'impostazione dell'applicazione contenente un token 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