.net ASP.NET 框架中的 Apple ID 身份验证不支持的授权类型错误
Apple ID Authentication in .net ASP.NET framework Unsupported Grant Type error
我正在编写一个服务器应用程序来处理来自 iOS 设备的 Apple ID 授权。
服务器是用 C# .net ASP.NET 框架编写的。
为了验证我正在使用此数据:
_config.ClientId
= com.organization.ios.app_name
,
_config.PrivateKeyId
- .p8 文件密钥 ID
_config._DevelopmentTeam
- code located before client id name ,X.com.organization.ios.app_name
that 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()),
new KeyValuePair<string, string>("code", passData.AuthCode);
new KeyValuePair<string, string>("grand_type", "authorization_code"),
new KeyValuePair<string, 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, 1, 0, 0, 0, 0, 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.
中的错别字
我正在编写一个服务器应用程序来处理来自 iOS 设备的 Apple ID 授权。 服务器是用 C# .net ASP.NET 框架编写的。
为了验证我正在使用此数据:
_config.ClientId
=com.organization.ios.app_name
,_config.PrivateKeyId
- .p8 文件密钥 ID_config._DevelopmentTeam
- code located before client id name ,X.com.organization.ios.app_name
that 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()),
new KeyValuePair<string, string>("code", passData.AuthCode);
new KeyValuePair<string, string>("grand_type", "authorization_code"),
new KeyValuePair<string, 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, 1, 0, 0, 0, 0, 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.