У меня есть файл .pem, предоставленный клиентом, и используя этот файл, я должен сгенерировать ключ client_secret, используя следующие пункты -
1.Учетная запись службы имеет открытый ключ из пары открытый-закрытый ключ
клиентом.
2. Метка времени отформатирована как десятичная строка, указывающая время в
миллисекунды после 1 января 1970 года 00:00:00 по Гринвичу.
3. Затем отметка времени подписывается / шифруется с использованием закрытого ключа службы.
Учетная запись связана с клиентом и закодирована в Base 64.
Я реализовал код в соответствии с вышеуказанным требованием, но сервер веб-API возвращает ошибку ниже -
Удаленный сервер возвратил ошибку: (400) Неверный запрос. {"error": "invalid_grant", "error_description": "Невозможно пройти проверку подлинности. [clientId:" my key "]."}.
Вот моя функция для генерации ключа client_secret -
private string getsecretkey()
{
string privateKeyPath = @"C:\Users\vijay.birari.DGSL\Desktop\Temp\familysearchserviceaccount1.PEM";
StreamReader sr = new StreamReader(privateKeyPath);
PemReader pr = new PemReader(sr);
AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
RSAParameters rsa = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
//RsaKeyParameters publickey = (RsaKeyParameters)KeyPair.Public;
RsaKeyParameters privatekey = (RsaKeyParameters)KeyPair.Private;
// Timestamps code
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
long millis = (long)ts.TotalMilliseconds;
string sTimestamp = Convert.ToString(millis);
byte[] Timstamp = Encoding.UTF8.GetBytes(sTimestamp);
IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine());
cipher.Init(true, privatekey);
byte[] bytesTimestampUtf8Encrypted = cipher.ProcessBlock(Timstamp, 0, Timstamp.Length);
string encode = Convert.ToBase64String(bytesTimestampUtf8Encrypted);
string secret = HttpUtility.UrlEncode(encode, UTF8Encoding.UTF8);
return secret;
}
вызов вышеуказанной функции в следующем коде -
string response = string.Empty;
try
{
StringBuilder sb = new StringBuilder("https://ident.familysearch.org/cis-web/oauth2/v3/token?");
sb.Append("grant_type=client_credentials&client_id=");
sb.Append(client_id);
sb.Append("&client_secret=");
// sb.Append("=");
sb.Append(getsecretkey());
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString());
request.Method = "POST";
// request.ContentType = "application/x-www-form-urlencoded";
// request.ContentType = "application/json";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
respones = sr.ReadToEnd();
}
if (!string.IsNullOrEmpty(respones))
{
dynamic jsonResponse = JsonConvert.DeserializeObject(respones.ToString());
dynamic data = JObject.Parse(respones);
respones = data.access_token;
}
}
return webresponse;
}
}
catch (WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
respones = reader.ReadToEnd();
//TODO: use JSON.net to parse this string and look at the error message
}
}
}
return respones;
}