问题描述
我正在编写一个处理来自iOS设备的Apple ID授权的服务器应用程序。 该服务器是使用C#.net ASP.NET框架编写的。
要进行身份验证,我正在使用以下数据:
-
_config.ClientId
=com.organization.ios.app_name
, -
_config.PrivateKeyId
-.p8文件密钥ID -
_config._DevelopmentTeam
-位于客户端ID名称X.com.organization.ios.app_name
之前的代码X, -
_config.PrivateKey
-.p8文件中的私钥
从iOS设备发出的请求中,我得到了
-
request.AuthCode
-授权码, -
request.IdentityToken
-令牌。
代码非常简单:
public Task<ResponseDTO> AuthenticateWithApple(RequestDTO request)
{
var contentData = new List<KeyValuePair<string,string>>()
{
new KeyValuePair<string,string>("client_id",_config.ClientId),new KeyValuePair<string,string>("client_secret",GenerateAppleJwtToken()),string>("code",passData.AuthCode);
new KeyValuePair<string,string>("grand_type","authorization_code"),string>("refresh_token","");
new KeyValuePair<string,string>("redirect_uri","");
};
try
{
var content = new FormUrlEncodedContent(contentData);
var response = await httpClient.PostAsync(_requestUrl,content);
var rawResponseData = await response.Content.ReadAsStringAsync();
if (response.StatusCode == HttpStatusCode.OK)
{
var responseData = JsonConvert.DeserializeObject<ResponseDTO>(rawResponseData);
return responseData;
}
else
{
var errorMessage = $"Status code {response.StatusCode}: \"{rawResponseData}\"";
throw new ArgumentException(errorMessage);
}
}
catch (Exception exc)
{
var error = new ErrorResponseViewModel();
var errorMessage = $"Problem encountered during authorization: {exc.Message}";
error.AddError(ErrorTypes.UNAUTHORIZED,nameof(AppleAuthenticationProvider),errorMessage);
return new ResponseDTO()
{
Errors = error
};
}
}
用于创建JWT客户端密码的是:
private string GenerateAppleJwtToken()
{
var issueTime = DateTime.Now;
var zeroTime = new DateTime(1970,1,DateTimeKind.Utc);
var iat = (int) issueTime.Subtract(zeroTime).TotalSeconds;
var exp = (int) issueTime.AddMinutes(5).Subtract(zeroTime).TotalSeconds;
var headers = new Dictionary<string,object>()
{
{ "alg","ES256" },{ "typ","JWT" },{ "kid",_config.PrivateKeyId },};
var payload = new Dictionary<string,object>()
{
{ "sub",_config.ClientId },{ "aud","https://appleid.apple.com" },{ "iss",_config.DevelopmentTeam },{ "exp",exp },{ "iat",iat }
};
var cngKey = CngKey.Import(Convert.FromBase64String(_config.PrivateKey),CngKeyBlobFormat.Pkcs8PrivateBlob);
var ecdsa = new ECDsaCng(cngKey);
byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(headers,Formatting.None));
byte[] claimsBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload,Formatting.None));
var base64Payload = Base64UrlEncoder.Encode(headerBytes) + "." + Base64UrlEncoder.Encode(claimsBytes);
var signature = ecdsa.SignData(Encoding.UTF8.GetBytes(base64Payload),HashAlgorithmName.SHA256);
return base64Payload + "." + Base64UrlEncoder.Encode(signature);
}
根据Apple ID授权的许多代码实现,这应该可以,但是不能。 错误消息是我收到的提示是:“ unsupported_grant_type ”
解决方法
您正在发送参数 grand_type
,但需要 grant_type
。注意 grand 中的拼写错误。