你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
将应用服务或 Azure Functions 应用配置为使用 Apple 登录提供程序(预览版)进行登录
本文介绍如何配置 Azure 应用服务或 Azure Functions,以便将 Apple 登录用作身份验证提供程序。
若要完成本文中的过程,你必须先在 Apple 开发人员计划中注册。 若要注册 Apple 开发人员计划,请转到 developer.apple.com/programs/enroll。
注意
启用 Apple 登录会禁止通过某些客户端(例如 Azure 门户、Azure CLI 和 Azure PowerShell)管理你的应用程序的应用服务身份验证/授权功能。 此功能依赖于一个新的 API 图面,该图面目前为预览版,并未应用于所有管理体验中。
在 Apple 开发人员门户中创建应用程序
需要在 Apple 开发人员门户中创建应用 ID 和服务 ID。
- 在 Apple 开发人员门户上,依次转到“证书”、“标识符”和“配置文件”。
- 在“标识符”选项卡上,选择 (+) 按钮 。
- 在“注册新的标识符”页上选择“应用 ID”,然后选择“继续” 。 (应用 ID 包括一个或多个服务 ID。)
- 在“注册应用 ID”页上,提供说明和捆绑 ID,然后从功能列表中选择“Apple 登录” 。 然后,选择“继续”。 记下此步骤中的应用 ID 前缀(团队 ID),稍后需要用到它。
- 查看应用注册信息,并选择“注册”。
- 同样,在“标识符”选项卡上,选择 (+) 按钮 。
- 在“注册新的标识符”页上选择“服务 ID”,然后选择“继续” 。
- 在“注册服务 ID”页上,提供说明和标识符。 说明内容将在同意屏幕上显示给用户。 此标识符将会是你的客户端 ID,用于对应用服务配置 Apple 提供程序。 然后选择“配置”。
- 在弹出窗口中,将主应用 ID 设置为之前创建的应用 ID。 在域部分中指定应用程序的域。 对于返回 URL,使用 URL
<app-url>/.auth/login/apple/callback
。 例如,https://contoso.azurewebsites.net/.auth/login/apple/callback
。 然后选择“添加”和“保存” 。 - 查看服务注册信息,然后选择“保存”。
生成客户端密码
Apple 要求应用开发人员创建 JWT 令牌并将其签名为客户端密码值。 若要生成此密码,首先从 Apple 开发人员门户生成椭圆曲线私钥并将其下载。 然后使用该密钥对具有特定有效负载的 JWT 进行签名。
创建和下载私钥
- 在 Apple 开发人员门户的“密钥”选项卡上,选择“创建密钥”或选择 (+) 按钮 。
- 在“注册新密钥”页上,为密钥指定一个名称,选中“Apple 登录”旁边的框,然后选择“配置” 。
- 在“配置密钥”页上,将密钥链接到之前创建的主应用 ID,然后选择“保存” 。
- 通过确认信息并选择“继续”,然后查看信息并选择“注册”来完成密钥的创建 。
- 在“下载密钥”页上,下载密钥。 它将下载为
.p8
(PKCS#8) 文件,你将使用文件内容对你的客户端密码 JWT 进行签名。
构建客户端密码 JWT
Apple 要求客户端密码是 base64 编码的 JWT 令牌。 解码后的 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 开发人员团队 ID
- aud:Apple 正在接收令牌,因此他们是受众
- exp:nbf 后不超过 6 个月
上述有效负载的 base64 编码版本如下所示:eyJhbGciOiJFUzI1NiIsImtpZCI6IlVSS0VZSUQwMDEifQ.eyJzdWIiOiJjb20ueW91cmNvbXBhbnkuYXBwMSIsIm5iZiI6MTU2MDIwMzIwNywiZXhwIjoxNTYwMjg5NjA3LCJpc3MiOiJBQkMxMjNERUZHIiwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSJ9.ABSXELWuTbgqfrIUz7bLi6nXvkXAz5O8vt0jB2dSHTQTib1x1DSP4__4UrlKI-pdzNg1sgeocolPNTmDKazO8-BHAZCsdeeTNlgFEzBytIpMKFfVEQbEtGRkam5IeclUK7S9oOva4EK4jV4VmgDrr-LGWWO3TaAxAvy3_ZoKohvFFkVG
注意:Apple 不接受创建(或 nbf)日期后到期日期超过 6 个月的客户端密码 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 开发人员团队 ID
- clientId:Apple 客户端 ID(也是服务 ID)
- p8key:PEM 格式密钥 - 获取密钥的方式如下:在文本编辑器中打开
.p8
文件,复制没有换行符的-----BEGIN PRIVATE KEY-----
和-----END PRIVATE KEY-----
之间的所有内容 - keyId:下载的密钥的 ID
返回的此令牌是用于配置 Apple 提供程序的客户端密码值。
重要
客户端密钥是一个非常重要的安全凭据。 请勿与任何人分享此密钥或在客户端应用程序中分发它。
使用你选择的设置名称将客户端机密添加为应用的应用程序设置。 记下此名称备用。
向应用程序添加提供者信息
注意
所需配置采用新的 API 格式,目前只有基于文件的配置(预览版)支持此格式。 你需要使用这样的文件执行以下步骤。
本部分将指导你更新配置,使之包括新的 IDP。 后面提供了配置示例。
在
identityProviders
对象内,添加一个apple
对象(如果它尚不存在)。向该密钥分配一个对象,在其中包含
registration
对象,还可以包含login
对象:"apple" : { "registration" : { "clientId": "<client ID>", "clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_CLIENT_SECRET" }, "login": { "scopes": [] } }
a. 在
registration
对象内,将clientId
设置为你收集的客户端 ID。b. 在
registration
对象内,将clientSecretSettingName
设置为存储客户端密码的应用程序设置的名称。c. 在
login
对象内,可选择将scopes
数组设置为包含使用 Apple 进行身份验证时所使用的范围列表,例如“名称”和“电子邮件”。 如果范围已配置,则在用户首次登录时,它们会在同意屏幕上被显式请求。
设置此配置后,即可在应用中使用 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
}
}
}