この記事では、認証プロバイダーとして Sign in with Apple を使用するように、Azure App Service または Azure Functions を構成する方法について説明します。
この記事の手順を完了するには、Apple Developer Program に登録しておく必要があります。 Apple Developer Program に登録するには、developer.apple.com/programs/enroll に移動します。
注意事項
Sign in with Apple を有効にすると、Azure portal、Azure CLI、Azure PowerShell などの一部のクライアントを介したアプリケーションの App Service の認証または承認機能の管理が無効になります。 この機能は、すべての管理エクスペリエンスに関してまだ考慮されていない、プレビュー段階の新しい API サーフェスに依存しています。
Apple Developer ポータルでアプリケーションを作成する
アプリ ID とサービス ID は、Apple Developer ポータルで作成する必要があります。
- Apple Developer ポータルで、[Certificates, Identifiers, & Profiles]\(証明書、ID、プロファイル\) に移動します。
- [Identifiers](ID) タブで、 [+] ボタンを選択します。
-
[Register a New Identifier](新しい ID の登録) ページで、 [App IDs](アプリ ID) を選び、 [Continue](続行) を選択します (App ID には 1 つ以上のサービス ID が含まれます。)

-
[Register an App ID](アプリ ID の登録) ページで、説明とバンドル ID を入力し、機能一覧から [Sign in with Apple] を選択します。 その後 [続行] を選択します。 この手順のご自分の [App ID Prefix (Team ID)](アプリ ID プレフィックス (チーム ID)) をメモしておいてください。これは後で必要になります。
- アプリの登録情報を確認し、 [Register](登録) を選択します。
- ここでも、 [Identifiers](ID) タブで [+] ボタンを選択します。
-
[Register a New Identifier](新しい ID の登録) ページで、 [Services IDs](サービス ID) を選び、 [Continue](続行) を選択します。
-
[Register a Services ID](サービス ID の登録) ページで、説明と識別子を入力します。 説明は、同意画面でユーザーに表示される内容です。 この識別子は、App Service で Apple プロバイダーを構成するときに使用されるクライアント ID になります。 次に、 [構成] を選択します。
- ポップアップ ウィンドウで、[Primary App ID](プライマリ アプリ ID) を、先ほど作成した App ID に設定します。 ドメイン セクションでアプリケーションのドメインを指定します。 リターン URL には、
<app-url>/.auth/login/apple/callbackURL を使用します。 たとえば、「https://contoso.azurewebsites.net/.auth/login/apple/callback」のように入力します。 その後、 [Add](追加) 、 [Save](保存) の順に選択します。
- サービスの登録情報を確認し、 [Save](保存) を選択します。
クライアント シークレットを生成する
Apple では、アプリ開発者がクライアント シークレット値として JWT を作成して署名する必要があります。 このシークレットを生成するには、まず、Apple Developer ポータルから楕円曲線の秘密キーを生成してダウンロードします。 その後、そのキーを使用し、特定のペイロードを使って JWT に署名します。
秘密キーを作成してダウンロードする
- Apple Developer ポータルの [Keys](キー) タブで、 [Create a key](キーの作成) を選ぶか、 [+] ボタンを選択します。
- [Register a New Key](新しいキーの登録) ページで、キーに名前を付け、 [Sign in with Apple] の横にあるチェックボックスをオンにして、 [Configure](構成) を選択します。
- [Configure Key](キーの構成) ページで、前に作成したプライマリ アプリ ID にキーをリンクし、 [Save](保存) を選択します。
- 情報を確認し、 [Continue](続行) を選択してから、情報を見直し、 [Register](登録) を選択してキーの作成を完了します。
-
[Download Your Key](自分のキーのダウンロード) ページで、キーをダウンロードします。 これは
.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 クライアント ID (サービス ID でもある)
- iss: ご利用の Apple Developer Team ID
- aud: Apple でトークンが受信されるため、それらが対象ユーザーとなります
- exp:nbf から 6 か月以内
上記のペイロードの base64 エンコード バージョンはこのようになります。eyJhbGciOiJFUzI1NiIsImtpZCI6IlVSS0VZSUQwMDEifQ.eyJzdWIiOiJjb20ueW91cmNvbXBhbnkuYXBwMSIsIm5iZiI6MTU2MDIwMzIwNywiZXhwIjoxNTYwMjg5NjA3LCJpc3MiOiJBQkMxMjNERUZHIiwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSJ9.ABSXELWuTbgqfrIUz7bLi6nXvkXAz5O8vt0jB2dSHTQTib1x1DSP4__4UrlKI-pdzNg1sgeocolPNTmDKazO8-BHAZCsdeeTNlgFEzBytIpMKFfVEQbEtGRkam5IeclUK7S9oOva4EK4jV4VmgDrr-LGWWO3TaAxAvy3_ZoKohvFFkVG
注: Apple では、有効期限が作成 (または nbf) 日から 6 か月を超えるクライアント シークレット JWT は受け入れられません。 つまり、クライアント シークレットは、少なくとも 6 か月ごとにローテーションする必要があります。
トークンの生成と確認の詳細については、Apple の開発者向けドキュメントを参照してください。
クライアント シークレット JWT に署名する
前にダウンロードした .p8 ファイルを使用して、クライアント シークレット JWT に署名します。 このファイルは PCKS#8 ファイルであり、PEM 形式の秘密署名キーが含まれています。 JWT の作成と署名に使用できるライブラリは多数あります。
JWT の作成と署名には、オンラインで使用できるさまざまな種類のオープン ソース ライブラリがあります。 JWT の生成の詳細については、「 JSON Web トークン (JWT)」を参照してください。 たとえば、クライアント シークレットを生成する方法の 1 つとして、NuGet の Microsoft.IdentityModel.Tokens パッケージをインポートし、以下に示す少量の 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 Developer Team ID
- clientId: Apple クライアント ID (サービス ID でもある)
-
p8key: PEM 形式のキー - テキスト エディターで
.p8ファイルを開き、改行なしで-----BEGIN PRIVATE KEY-----と-----END PRIVATE KEY-----の間のすべてをコピーすることで、キーを取得できます。 - keyId: ダウンロードされたキーの ID
この返されたトークンが、Apple プロバイダーの構成に使用するクライアント シークレットの値となります。
重要
クライアント シークレットは、重要なセキュリティ資格情報です。 このシークレットを他のユーザーと共有したり、クライアント アプリケーション内で配信したりしないでください。
選択した設定名を使用して、クライアント シークレットをアプリのアプリケーション設定として追加します。 後で使用するためにこの名前をメモしておきます。
アプリケーションにプロバイダー情報を追加する
Note
必要な構成は新しい API 形式ですが、現時点では ファイルベースの構成 (プレビュー) でのみサポートされています。 このようなファイルを使用して、以下の手順を行う必要があります。
このセクションでは、新しい IDP を含めるように構成を更新する手順について説明します。 構成の例を次に示します。
identityProvidersオブジェクト内にappleオブジェクトがまだ存在しない場合は追加します。オブジェクトを
registrationオブジェクトが含まれているそのキーに割り当て、オプションでloginオブジェクトを割り当てます。"apple" : { "registration" : { "clientId": "<client ID>", "clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_CLIENT_SECRET" }, "login": { "scopes": [] } }a.
registrationオブジェクト内で、収集したクライアント ID にclientIdを設定します。b.
registrationオブジェクト内で、クライアント シークレットを格納したアプリケーション設定の名前にclientSecretSettingNameを設定します。c.
loginオブジェクト内で、"name" や "email" など、Apple での認証時に使用されるスコープの一覧を含めるようにscopes配列を設定することを選択できます。 スコープが構成されている場合は、ユーザーが初めてサインインするときに同意画面でそれらが明示的に要求されます。
この構成が設定されると、アプリで認証に 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
}
}
}