將 App Service 或 Azure Functions 應用程式設定為以「使用 Apple 登入」提供者來登入 (預覽)

本文說明如何將 Azure App Service 或 Azure Functions 設定為以「使用 Apple 登入」作為驗證提供者。

若要完成本文中的程序,您必須已加入 Apple 開發人員計劃。 若要加入 Apple 開發人員計劃,請前往 developer.apple.com/programs/enroll

警告

啟用「使用 Apple 登入」會導致無法透過某些用戶端來管理應用程式的 App Service 驗證/授權功能,例如 Azure 入口網站、Azure CLI 和 Azure PowerShell。 此功能依賴新的 API 介面,這在預覽期間尚未納入所有管理體驗中。

在 Apple Developer 入口網站中建立應用程式

您必須在 Apple Developer 入口網站中建立應用程式識別碼和服務識別碼。

  1. 在 Apple 開發人員入口網站上,移至 [憑證、識別碼和設定檔]
  2. 在 [識別碼] 索引標籤上,選取 [(+)] 按鈕。
  3. 在 [註冊新的識別碼] 頁面上,選擇 [應用程式識別碼],然後選取 [繼續]。 (應用程式識別碼包含一或多個服務識別碼。) Registering a new app identifier in the Apple Developer Portal
  4. 在 [註冊應用程式識別碼] 頁面上,提供描述和組合識別碼,然後從功能清單中選取 [使用 Apple 登入]。 然後選取 [繼續]。 記下此步驟中的 [應用程式識別碼前置詞 (小組識別碼)],稍後需要用到。 Configuring a new app identifier in the Apple Developer Portal
  5. 檢閱應用程式註冊資訊,然後選取 [註冊]
  6. 在 [識別碼] 索引標籤上,再次選取 [(+)] 按鈕。 Creating a new service identifier in the Apple Developer Portal
  7. 在 [註冊新的識別碼] 頁面上,選擇 [服務識別碼],然後選取 [繼續]Registering a new service identifier in the Apple Developer Portal
  8. 在 [註冊服務識別碼] 頁面上,提供描述和識別碼。 使用者在同意畫面上會看到此描述。 此識別碼是為應用程式服務設定 Apple 提供者時使用的用戶端識別碼。 然後選取 [設定]Providing a description and an identifier
  9. 在快顯視窗中,將 [主要應用程式識別碼] 設定為您稍早建立的應用程式識別碼。 在網域區段中指定應用程式的網域。 使用 URL <app-url>/.auth/login/apple/callback 作為返回 URL。 例如: https://contoso.azurewebsites.net/.auth/login/apple/callback 。 然後選取 [新增] 和 [儲存]Specifying the domain and return URL for the registration
  10. 檢閱服務註冊資訊,然後選取 [儲存]

產生用戶端密碼

Apple 需要應用程式開發人員建立 JWT 權杖,並簽署為用戶端密碼值。 若要產生此秘密,請先從 Apple Developer 入口網站產生並下載橢圓曲線私密金鑰。 然後,使用該金鑰以特定承載簽署 JWT

建立並下載私密金鑰

  1. 在 Apple 開發人員入口網站的 [金鑰] 索引標籤上,選擇 [建立金鑰],或選取 [(+)] 按鈕。
  2. 在 [註冊新的金鑰] 頁面上,命名金鑰,核取 [使用 Apple 登入] 旁的方塊,然後選取 [設定]
  3. 在 [設定金鑰] 頁面上,將金鑰連結至您先前建立的主要應用程式識別碼,然後選取 [儲存]
  4. 確認資訊並選取 [繼續],然後檢閱資訊並選取 [註冊],以完成建立金鑰。
  5. 在 [下載金鑰] 頁面上,下載金鑰。 將下載為 .p8 (PKCS#8) 檔案 - 您將使用檔案內容來簽署用戶端密碼 JWT。

建構用戶端密碼 JWT

Apple 要求用戶端密碼是 JWT 權杖的 base64 編碼。 解碼的 JWT 權杖應該具有類似下列範例的承載結構:

{
  "alg": "ES256",
  "kid": "URKEYID001",
}.{
  "sub": "com.yourcompany.app1",
  "nbf": 1560203207,
  "exp": 1560289607,
  "iss": "ABC123DEFG",
  "aud": "https://appleid.apple.com"
}.[Signature]
  • sub:Apple 用戶端識別碼 (也是服務識別碼)
  • iss:Apple 開發人員小組識別碼
  • aud:Apple 接收權杖,因此是對象
  • expnbf 之後不超過六個月

上述承載的 base64 編碼版本看起來像這樣:eyJhbGciOiJFUzI1NiIsImtpZCI6IlVSS0VZSUQwMDEifQ.eyJzdWIiOiJjb20ueW91cmNvbXBhbnkuYXBwMSIsIm5iZiI6MTU2MDIwMzIwNywiZXhwIjoxNTYwMjg5NjA3LCJpc3MiOiJBQkMxMjNERUZHIiwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSJ9.ABSXELWuTbgqfrIUz7bLi6nXvkXAz5O8vt0jB2dSHTQTib1x1DSP4__4UrlKI-pdzNg1sgeocolPNTmDKazO8-BHAZCsdeeTNlgFEzBytIpMKFfVEQbEtGRkam5IeclUK7S9oOva4EK4jV4VmgDrr-LGWWO3TaAxAvy3_ZoKohvFFkVG

注意:Apple 不接受到期日在建立 (或 nbf) 日期之後超過六個月的用戶端密碼 JWT。 這表示至少每六個月必須輪替一次用戶端密碼。

如需有關產生和驗證權杖的詳細資訊,請參閱 Apple 的開發人員文件

簽署用戶端密碼 JWT

使用您先前下載的 .p8 檔案來簽署用戶端密碼 JWT。 此檔案是 PCKS#8 檔案,其中包含 PEM 格式的私人簽署金鑰。 有許多程式庫可以為您建立和簽署 JWT。

線上提供各種開放原始碼程式庫,可用來建立和簽署 JWT 權杖。 如需有關產生 JWT 權杖的詳細資訊,請參閱 JSON Web 權杖 (JWT)。 例如,產生用戶端密碼的一種方式是匯入 Microsoft.IdentityModel.Tokens NuGet 封裝,並執行如下所示的少量 C# 程式碼。

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:Apple 開發人員小組識別碼
  • clientId:Apple 用戶端識別碼 (也是服務識別碼)
  • p8key:PEM 格式金鑰 - 您可在文字編輯器中開啟 .p8 檔案,並複製 -----BEGIN PRIVATE KEY----------END PRIVATE KEY----- 之間的所有內容 (不包括分行符號),以取得金鑰
  • keyId:所下載金鑰的識別碼

傳回的權杖是用來設定 Apple 提供者的用戶端密碼值。

重要

用戶端密碼是重要的安全性認證。 請勿與任何人共用此密碼,或在用戶端應用程式中加以散發。

使用您選擇的設定名稱,將用戶端密碼新增為應用程式的應用程式設定。 記下此名稱供稍後使用。

將提供者資訊新增至應用程式

注意

必要的設定是新的 API 格式,目前只有以檔案為基礎的設定 (預覽) 才支援。 您必須使用此檔案來遵循下列步驟。

本節逐步引導您更新設定來包含新的 IDP。 範例設定如下。

  1. identityProviders 物件內,新增 apple 物件 (如果不存在)。

  2. 將物件指派給該索引鍵,內有 registration 物件,還可能有 login 物件:

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

    a. 在 registration 物件內,將 clientId 設定為您收集的用戶端識別碼。

    b. 在 registration 物件內,將 clientSecretSettingName 設定為您應用程式設定的名稱,其中儲存用戶端密碼。

    c. 在 login 物件內,您可以選擇設定 scopes 陣列以包含向 Apple 進行驗證時所使用的範圍清單,例如 "name" 和 "email"。 如果已設定範圍,當使用者第一次登入時,同意畫面上會明確要求這些範圍。

完成此設定之後,您就可以在應用程式中使用 Apple 提供者進行驗證。

完整設定可能如下列範例所示 (其中,APPLE_GENERATED_CLIENT_SECRET 設定指向的應用程式設定包含已產生的 JWT):

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

後續步驟