/// <summary> /// Validation iOS /// </summary> /// <param name="param">subumission parameter</param> /// <returns>True when successful.</returns> /// <remarks> /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data /// </remarks> public async Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime, AuthorizedAppInformation app) { var payload = new ApplePayload() { DeviceToken = param.DeviceVerificationPayload, Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; var keysText = param.Keys .OrderBy(_ => _.KeyData) .Select(_ => _.KeyData) .Aggregate((a, b) => a + b); using (var sha = System.Security.Cryptography.SHA256.Create()) { var value = System.Text.Encoding.UTF8.GetBytes(param.AppPackageName + keysText + string.Join(',', param.Regions)); payload.TransactionId = Convert.ToBase64String(sha.ComputeHash(value)); } var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey); var content = new StringContent(JsonConvert.SerializeObject(payload)); var request = new HttpRequestMessage(HttpMethod.Post, UrlApple); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt); var response = await ClientApple.SendAsync(request); //switch (response.StatusCode) //{ // // 200 OK: The transaction was successful // // 200 Bit State Not Found: The bit state wasn't found // case System.Net.HttpStatusCode.OK: // if (response.ReasonPhrase == "OK") return true; // break; // // // default: // break; //} if (response.StatusCode != System.Net.HttpStatusCode.OK) { return(false); } return(true); }
/// <summary> /// Validation iOS /// </summary> /// <param name="param">subumission parameter</param> /// <returns>True when successful.</returns> /// <remarks> /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data /// </remarks> public async Task <bool> Validation(IAppleDeviceVerification deviceVerification, DateTimeOffset requestTime, AuthorizedAppInformation app) { var payload = new ApplePayload() { DeviceToken = deviceVerification.DeviceToken, Timestamp = requestTime.ToUnixTimeMilliseconds() }; using (var sha = SHA256.Create()) { payload.TransactionId = Convert.ToBase64String( sha.ComputeHash(Encoding.UTF8.GetBytes(deviceVerification.TransactionIdSeed)) ); } Logger.LogInformation($"{nameof(Validation)} DeviceCheckKeyId:{app.DeviceCheckKeyId} DeviceCheckTeamId:{app.DeviceCheckTeamId} DeviceCheckPrivateKey:{app.DeviceCheckPrivateKey}"); var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey); var payloadJson = JsonConvert.SerializeObject(payload); Logger.LogInformation($"{nameof(Validation)} payload:{payloadJson} "); var request = new HttpRequestMessage(HttpMethod.Post, UrlApple); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt); request.Content = new StringContent(payloadJson, Encoding.UTF8, "application/json"); try { var response = await ClientApple.SendAsync(request); if (!response.IsSuccessStatusCode) { Logger.LogWarning($"iOS device check failed.\r\n{nameof(HttpRequestMessage)} : {request}\r\n{nameof(HttpResponseMessage)} : {response}"); } return(response.StatusCode == System.Net.HttpStatusCode.OK); } catch (Exception ex) { Logger.LogError(ex, $"{nameof(Validation)}"); throw; } }
/// <summary> /// Validation iOS /// </summary> /// <param name="param">subumission parameter</param> /// <returns>True when successful.</returns> /// <remarks> /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data /// </remarks> public async Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime, AuthorizedAppInformation app) { var payload = new ApplePayload() { DeviceToken = param.DeviceVerificationPayload, Timestamp = requestTime.ToUnixTimeMilliseconds() }; var keysText = string.Empty; if (param is V1DiagnosisSubmissionParameter) { keysText = (param as V1DiagnosisSubmissionParameter).Keys .OrderBy(_ => _.KeyData) .Select(_ => _.KeyData) .Aggregate((a, b) => a + b); } else { keysText = param.Keys .OrderBy(_ => _.KeyData) .Select(_ => _.KeyData) .Aggregate((a, b) => a + b); } using (var sha = System.Security.Cryptography.SHA256.Create()) { var value = System.Text.Encoding.UTF8.GetBytes(param.AppPackageName + keysText + string.Join(',', param.Regions)); payload.TransactionId = Convert.ToBase64String(sha.ComputeHash(value)); } Logger.LogInformation($"{nameof(Validation)} DeviceCheckKeyId:{app.DeviceCheckKeyId} DeviceCheckTeamId:{app.DeviceCheckTeamId} DeviceCheckPrivateKey:{app.DeviceCheckPrivateKey}"); var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey); var payloadJson = JsonConvert.SerializeObject(payload); Logger.LogInformation($"{nameof(Validation)} payload:{payloadJson} "); var request = new HttpRequestMessage(HttpMethod.Post, UrlApple); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt); request.Content = new StringContent(payloadJson, Encoding.UTF8, "application/json"); try { var response = await ClientApple.SendAsync(request); if (!response.IsSuccessStatusCode) { var responseBody = await response.Content.ReadAsStringAsync(); Logger.LogWarning($"POST {UrlApple} {response.StatusCode} {response.ReasonPhrase} {responseBody}"); } //switch (response.StatusCode) //{ // // 200 OK: The transaction was successful // // 200 Bit State Not Found: The bit state wasn't found // case System.Net.HttpStatusCode.OK: // if (response.ReasonPhrase == "OK") return true; // break; // // // default: // break; //} if (response.StatusCode != System.Net.HttpStatusCode.OK) { return(false); } return(true); } catch (Exception ex) { Logger.LogError(ex, $"{nameof(Validation)}"); throw; } }
/// <summary> /// Validation iOS /// </summary> /// <param name="param">subumission parameter</param> /// <returns>True when successful.</returns> /// <remarks> /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data /// </remarks> public async Task <bool> Validation(IAppleDeviceVerification deviceVerification, DateTimeOffset requestTime, AuthorizedAppInformation app) { var payload = new ApplePayload() { DeviceToken = deviceVerification.DeviceToken, Timestamp = requestTime.ToUnixTimeMilliseconds() }; using (var sha = SHA256.Create()) { payload.TransactionId = Convert.ToBase64String( sha.ComputeHash(Encoding.UTF8.GetBytes(deviceVerification.TransactionIdSeed)) ); } Logger.LogInformation($"{nameof(Validation)} DeviceCheckKeyId:{app.DeviceCheckKeyId} DeviceCheckTeamId:{app.DeviceCheckTeamId} DeviceCheckPrivateKey:{app.DeviceCheckPrivateKey}"); var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey); var payloadJson = JsonConvert.SerializeObject(payload); Logger.LogInformation($"{nameof(Validation)} payload:{payloadJson} "); var request = new HttpRequestMessage(HttpMethod.Post, UrlApple); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt); request.Content = new StringContent(payloadJson, Encoding.UTF8, "application/json"); try { var response = await ClientApple.SendAsync(request); if (!response.IsSuccessStatusCode) { var responseBody = await response.Content.ReadAsStringAsync(); Logger.LogWarning($"iOS device check failed.\r\n{nameof(HttpRequestMessage)} : {request}\r\n{nameof(HttpResponseMessage)} : {response}"); } //switch (response.StatusCode) //{ // // 200 OK: The transaction was successful // // 200 Bit State Not Found: The bit state wasn't found // case System.Net.HttpStatusCode.OK: // if (response.ReasonPhrase == "OK") return true; // break; // // // default: // break; //} if (response.StatusCode != System.Net.HttpStatusCode.OK) { // FIXME: When call iOS Device check, return error sometimes, Until the cause is known, ignored device check return(true); } return(true); } catch (Exception ex) { Logger.LogError(ex, $"{nameof(Validation)}"); throw; } }