[성현모] VPKI Http Service Core dll적용

This commit is contained in:
SHM
2025-04-28 11:26:41 +09:00
parent b606d39577
commit 6f708d55fd
19 changed files with 121 additions and 212 deletions

Binary file not shown.

View File

@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
@ -14,7 +15,7 @@ namespace SystemX.Core.Communication
/// </summary>
/// <param name="url">https://127.0.0.1:443</param>
/// <param name="timeOutSeconds">Range 5~30 secconds</param>
public virtual async Task<RESPONSE?> PostJsonAsync<REQUEST, RESPONSE>(string url, REQUEST request, short timeOutSeconds = 5) where REQUEST : class where RESPONSE : class
public virtual async Task<RESPONSE?> PostJsonAsync<REQUEST, RESPONSE>(string url, REQUEST request, string bearerToken = "", short timeOutSeconds = 5) where REQUEST : class where RESPONSE : class
{
RESPONSE? response = default(RESPONSE);
Guid guid = Guid.NewGuid();
@ -25,6 +26,9 @@ namespace SystemX.Core.Communication
httpClient.Timeout = new TimeSpan(0, 0, timeOutSec);
httpClient.BaseAddress = new Uri($"{url}");
if(string.IsNullOrEmpty(bearerToken) == false)
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $"{bearerToken}");
int retry = 0;
while (true)
{
@ -59,7 +63,7 @@ namespace SystemX.Core.Communication
/// </summary>
/// <param name="url">https://127.0.0.1:443</param>
/// <param name="timeOutSeconds">Range 5~30 secconds</param>
public virtual async Task<RESPONSE?> GetJsonAsync<RESPONSE>(string url, short timeOutSeconds = 10) where RESPONSE : class
public virtual async Task<RESPONSE?> GetJsonAsync<RESPONSE>(string url, string bearerToken = "", short timeOutSeconds = 10) where RESPONSE : class
{
RESPONSE? response = default(RESPONSE);
Guid guid = Guid.NewGuid();
@ -72,6 +76,9 @@ namespace SystemX.Core.Communication
httpClient.Timeout = new TimeSpan(0, 0, timeOutSec);
httpClient.BaseAddress = new Uri($"{url}");
if (string.IsNullOrEmpty(bearerToken) == false)
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $"{bearerToken}");
Log4net.WriteLine($"[GET] Request({guid})::{url}", LogType.HTTP);
DateTime requestTime = DateTime.Now;
@ -88,6 +95,7 @@ namespace SystemX.Core.Communication
return response;
}
protected HttpClientHandler GetClientHandler()
{
HttpClientHandler clientHandler = new HttpClientHandler();

View File

@ -12,14 +12,6 @@ namespace SystemX.Core.DB
{
public static class DBTransaction
{
/// <summary>
/// Get SqlServer Connection String
/// </summary>
public static string ConvertToConnectionString(this DataBase dbConfig)
{
return $"server={dbConfig.IP},{dbConfig.Port}; user id={dbConfig.UserID}; password={dbConfig.Password}; database={dbConfig.DBName}; TrustServerCertificate=true;";
}
public static IEnumerable<TEntity>? GetEntity<TEntity>(this DbContext dbContext) where TEntity : class
{
IEnumerable<TEntity>? entity = default;

View File

@ -16,6 +16,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="log4net" Version="3.0.4" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.15" />

View File

@ -0,0 +1,28 @@
using CsvHelper.Configuration;
using CsvHelper;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
public static class CsvUtils
{
public static async Task<byte[]> ExportToCsvByteArray<T>(this IEnumerable<T> data) where T : class
{
using var memoryStream = new MemoryStream();
using var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8);
using var csvWriter = new CsvWriter(streamWriter, new CsvConfiguration(CultureInfo.InvariantCulture));
await csvWriter.WriteRecordsAsync(data);
await streamWriter.FlushAsync();
memoryStream.Position = 0;
return memoryStream.ToArray();
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SystemX.Core.Config.Model;
public static class DBUtils
{
/// <summary>
/// Get SqlServer Connection String
/// </summary>
public static string ConvertToConnectionString(this DataBase dbConfig)
{
return $"server={dbConfig.IP},{dbConfig.Port}; user id={dbConfig.UserID}; password={dbConfig.Password}; database={dbConfig.DBName};";
}
}

View File

@ -1,112 +0,0 @@
using System.Net.Http.Json;
namespace VPKI.Library.Services
{
public class HttpService : CommonService
{
public HttpService()
: base()
{
}
/// <summary>
/// PostJsonAsync
/// </summary>
/// <param name="url">https://127.0.0.1:443</param>
/// <param name="timeOutSeconds">Range 5~30 secconds</param>
public virtual async Task<RESPONSE?> PostJsonAsync<REQUEST, RESPONSE>(string url, REQUEST request, short timeOutSeconds = 5) where REQUEST : class where RESPONSE : class
{
RESPONSE? response = default(RESPONSE);
Guid guid = Guid.NewGuid();
using (HttpClient httpClient = new HttpClient(GetClientHandler()))
{
int retry = 0;
while (true)
{
await Task.Delay(1);
try
{
var timeOutSec = SetTimeout(timeOutSeconds);
httpClient.Timeout = new TimeSpan(0, 0, timeOutSec);
httpClient.BaseAddress = new Uri($"{url}");
Log4net.WriteLine($"[POST] Request({guid})::{url}{Environment.NewLine}{request?.ToJson()}", LogType.HTTP);
DateTime requestTime = DateTime.Now;
var res = await httpClient.PostAsJsonAsync(url, request);
response = await res.Content.ReadFromJsonAsync<RESPONSE>();
Log4net.WriteLine($"[POST] Rseponse({guid}) ({(DateTime.Now - requestTime).TotalSeconds} sec)::{url}{Environment.NewLine}{response?.ToJson()}", LogType.HTTP);
break;
}
catch (Exception e)
{
Log4net.WriteLine(e);
retry += 1;
}
if (retry > 1)
break;
}
}
return response;
}
/// <summary>
/// GetJsonAsnyc
/// </summary>
/// <param name="url">https://127.0.0.1:443</param>
/// <param name="timeOutSeconds">Range 5~30 secconds</param>
public virtual async Task<RESPONSE?> GetJsonAsync<RESPONSE>(string url, short timeOutSeconds = 10) where RESPONSE : class
{
RESPONSE? response = default(RESPONSE);
Guid guid = Guid.NewGuid();
using (HttpClient httpClient = new HttpClient(GetClientHandler()))
{
try
{
var timeOutSec = SetTimeout(timeOutSeconds);
httpClient.Timeout = new TimeSpan(0, 0, timeOutSec);
httpClient.BaseAddress = new Uri($"{url}");
Log4net.WriteLine($"[GET] Request({guid})::{url}", LogType.HTTP);
DateTime requestTime = DateTime.Now;
response = await httpClient.GetFromJsonAsync<RESPONSE>(url);
Log4net.WriteLine($"[GET] Rseponse({guid}) ({(DateTime.Now - requestTime).TotalSeconds} sec)::{url}", LogType.HTTP);
}
catch (Exception e)
{
Log4net.WriteLine(e);
}
}
return response;
}
protected HttpClientHandler GetClientHandler()
{
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
{
return true;
};
return clientHandler;
}
protected short SetTimeout(short timeOutSeconds)
{
short timeoutMin = 5;
short timeoutMax = 30;
timeOutSeconds = Math.Clamp(timeOutSeconds, timeoutMin, timeoutMax);
return timeOutSeconds;
}
}
}

View File

@ -7,6 +7,7 @@ using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Pkcs;
using System.Security.Cryptography;
using System.Text;
using SystemX.Core.Communication;
using SystemX.Core.DB;
using VPKI.Library.Config;
using VPKI.Library.Enums;
@ -210,7 +211,8 @@ namespace VPKI.Web.Api.Services
string url = $"{URL_VPKI_BASE}{URL_V1_CERTIFICATE_ISSUE}";
url = url.Replace("{1}", "prov");
responseOem = await PostJsonAsync<Request_CertificateOEM, Response_CertificateOEM>($"{url}", requestOem);
var http = new Http();
responseOem = await http.PostJsonAsync<Request_CertificateOEM, Response_CertificateOEM>($"{url}", requestOem);
response.status = responseOem?.status;
response.message = $"{responseOem?.resultMessage}";

View File

@ -12,6 +12,7 @@ using Org.BouncyCastle.Asn1.X9;
using DB.VPKI_DataDB;
using Microsoft.EntityFrameworkCore;
using SystemX.Core.DB;
using SystemX.Core.Communication;
namespace VPKI.Web.Api.Services
{
@ -221,7 +222,8 @@ namespace VPKI.Web.Api.Services
string url = $"{URL_VPKI_BASE}{URL_V2_CERTIFICATE_ISSUE}";
url = url.Replace("{1}", $"{vpkiType.ToString().Split("_").FirstOrDefault()}");
responseOem = await PostJsonAsync<Request_CertificateOEM, Response_CertificateOEM>(url, requestOem);
var http = new Http();
responseOem = await http.PostJsonAsync<Request_CertificateOEM, Response_CertificateOEM>(url, requestOem);
response.status = responseOem?.status;
response.message = $"{responseOem?.resultMessage}";

View File

@ -23,7 +23,7 @@ using VPKI.Library.Services;
namespace VPKI.Web.Api.Services
{
public class VpkiBaseService : HttpService
public class VpkiBaseService
{
private readonly IServiceScopeFactory _scopeFactory;

View File

@ -1,4 +1,5 @@
@using System.Security.Claims
@using SystemX.Core.Communication
@using VPKI.Library.Model.Auth
@inject NavigationManager NavigationManager
@ -73,7 +74,11 @@
};
await((ExtendAuthenticationStatProvicer)AuthStateProvider).MakeUserLogout();
var res = await ApiService.PostJsonAsyncBearer<LogoutModel, LogoutResponseModel>("/api/auth/logout", logoutModel);
var token = await ApiService.GetSessionState();
var http = new Http();
var res = await http.PostJsonAsync<LogoutModel, LogoutResponseModel>("https://127.0.0.1:8080/api/auth/logout", logoutModel, $"{token}");
NavigationManager.NavigateTo("/login");
}

View File

@ -5,6 +5,7 @@
@using Org.BouncyCastle.Crypto.Parameters
@using Org.BouncyCastle.OpenSsl
@using Org.BouncyCastle.Security
@using SystemX.Core.Communication
@using VPKI.Library.Packet
@inject CertificateService CertificateService
@ -190,7 +191,8 @@
url = $"api/v2/vehicle/certificate";
}
var Response = await ApiService.PostJsonAsync<Request_Certificate, Response_Certificate>($"https://{ServerAddress}/{url}", request);
var http = new Http();
var Response = await http.PostJsonAsync<Request_Certificate, Response_Certificate>($"https://{ServerAddress}/{url}", request);
if (Response != null)
{
CertificateContainer.ResponseCertificate = Response;

View File

@ -1,5 +1,6 @@
@using Org.BouncyCastle.Crypto
@using Org.BouncyCastle.Crypto.Parameters
@using SystemX.Core.Communication
@using VPKI.Library.Packet
@inject CertificateService CertificateService
@ -194,7 +195,8 @@
url = $"api/v2/vehicle/tbscsr";
}
var Response = await ApiService.PostJsonAsync<Request_Tbscsr, Response_Tbscsr>($"https://{ServerAddress}/{url}", request);
var http = new Http();
var Response = await http.PostJsonAsync<Request_Tbscsr, Response_Tbscsr>($"https://{ServerAddress}/{url}", request);
if (Response != null)
{
TbscsrContainer.ResponseTbscsr = Response;

View File

@ -1,4 +1,5 @@
@using VPKI.Library.Packet
@using SystemX.Core.Communication
@using VPKI.Library.Packet
@inject CertificateService CertificateService
@inject ApiService ApiService
@ -89,7 +90,8 @@
url = $"api/v2/vehicle/verifyresult";
}
var Response = await ApiService.PostJsonAsync<Request_Verifyresult, Response_Verifyresult>($"https://{ServerAddress}/{url}", request);
var http = new Http();
var Response = await http.PostJsonAsync<Request_Verifyresult, Response_Verifyresult>($"https://{ServerAddress}/{url}", request);
if (Response != null)
{
VerifyResultContainer.ResponseVerifyresult = Response;

View File

@ -1,4 +1,5 @@
@page "/login"
@using SystemX.Core.Communication
@inject NavigationManager NavigationManager
@inject ApiService ApiService
@ -49,7 +50,10 @@
LoginModel.Password = $"{LoginModel.Password?.StringToSHA256Base64()}";
ErrorCode = string.Empty;
var res = await ApiService.PostJsonAsyncBearer<LoginModel, LoginResponseModel>($"/api/auth/login", LoginModel);
var token = await ApiService.GetSessionState();
var http = new Http();
var res = await http.PostJsonAsync<LoginModel, LoginResponseModel>($"https://127.0.0.1:8080/api/auth/login", LoginModel, $"{token}");
if (res?.AccessToken != null)
{
await ((ExtendAuthenticationStatProvicer)AuthStateProvider).MakeUserAsAuthenticated(res);

View File

@ -1,4 +1,5 @@
@page "/register"
@using SystemX.Core.Communication
@inject NavigationManager NavigationManager
@inject ApiService ApiService
@ -67,7 +68,11 @@
//password hash
RegisterModel.Password = $"{RegisterModel.Password?.StringToSHA256Base64()}";
RegisterModel.PasswordConfirm = $"{RegisterModel.PasswordConfirm?.StringToSHA256Base64()}";
var res = await ApiService.PostJsonAsyncBearer<RegisterModel, RegisterResponseModel>($"/api/auth/regisger", RegisterModel);
var token = await ApiService.GetSessionState();
var http = new Http();
var res = await http.PostJsonAsync<RegisterModel, RegisterResponseModel>($"https://127.0.0.1:8080/api/auth/regisger", RegisterModel, $"{token}");
if (res != null)
{
if (res.EC == ERROR_CODE.EC_OK)

View File

@ -1,4 +1,5 @@
@page "/user"
@using SystemX.Core.Communication
@inject ApiService ApiService
@inject VpkiDialogService DialogService
@ -95,7 +96,11 @@
if(confirm == true)
{
user.TRole.CRoleName = $"{Enum.GetName(typeof(UserRole), user.TRole.CRoleId)}";
var retunUser = await ApiService.PostJsonAsyncBearer<UserModel, UserModel>("/api/user/UpdateUser", user);
var token = await ApiService.GetSessionState();
var http = new Http();
var retunUser = await http.PostJsonAsync<UserModel, UserModel>("https://127.0.0.1:8080/api/user/UpdateUser", user, $"{token}");
if (retunUser != null)
{
await GetAllUsers();
@ -114,7 +119,10 @@
private async Task GetAllUsers()
{
var response = await ApiService.GetJsonAsyncBearer<List<UserModel>>("/api/user/GetAllUser");
var http = new Http();
var token = await ApiService.GetSessionState();
var response = await http.GetJsonAsync<List<UserModel>>("https://127.0.0.1:8080/api/user/GetAllUser", $"{token}");
if (response != null)
{
data = response.OrderBy(x=>x.TUser.CCreateDateTime).ToList();

View File

@ -1,6 +1,7 @@
@page "/vpki/manager"
@using DB.VPKI_DataDB
@using System.Text
@using SystemX.Core.Communication
@using VPKI.Library.Packet
@using VPKI.Library.Static
@ -199,7 +200,7 @@
//Default filter
requestUrl += $"startDate={SearchStartDate}&";
requestUrl += $"endDate={SearchEndDate}&";
// requestUrl += $"startCcuid={startCcuid}&";
// requestUrl += $"startCcuid={startCcuid}&";
//optional filter
// if (string.IsNullOrEmpty(FilterIft) == false)
@ -220,7 +221,8 @@
// }
history?.Clear();
var result = await ApiService.GetJsonAsync<List<CertificateHistoryModel>>(requestUrl);
var http = new Http();
var result = await http.GetJsonAsync<List<CertificateHistoryModel>>(requestUrl);
if (result != null)
{
history.AddRange(result);
@ -264,11 +266,12 @@
api = "api/v2/vehicle/reissue";
}
var result = await ApiService.PostJsonAsync<Request_Certificate, Response_Certificate>($"https://{ServerAddress}/{api}", requestReissue);
var http = new Http();
var result = await http.PostJsonAsync<Request_Certificate, Response_Certificate>($"https://{ServerAddress}/{api}", requestReissue);
if (result != null)
{
string requestUrl = $"https://{ServerAddress}/history/ccuid?ccuid={args.TTbscsr.CCuid}";
var updateResult = await ApiService.GetJsonAsync<CertificateHistoryModel>(requestUrl);
var updateResult = await http.GetJsonAsync<CertificateHistoryModel>(requestUrl);
if (updateResult != null)
{
args.TTbscsr = updateResult.TTbscsr;
@ -316,11 +319,12 @@
api = "api/v2/vehicle/revoke";
}
var result = await ApiService.PostJsonAsync<Request_CertificateRevokeOEM, Response_CertificateRevokeOEM>($"https://{ServerAddress}/{api}", requestRevoke);
var http = new Http();
var result = await http.PostJsonAsync<Request_CertificateRevokeOEM, Response_CertificateRevokeOEM>($"https://{ServerAddress}/{api}", requestRevoke);
if (result != null)
{
string requestUrl = $"https://{ServerAddress}/history/ccuid?ccuid={args.TTbscsr.CCuid}";
var updateResult = await ApiService.GetJsonAsync<CertificateHistoryModel>(requestUrl);
var updateResult = await http.GetJsonAsync<CertificateHistoryModel>(requestUrl);
if (updateResult != null)
{
args.TTbscsr = updateResult.TTbscsr;
@ -425,9 +429,11 @@
DialogService.OpenIndicator("Export to Prov Certificate");
if (certificate != null)
{
{
var http = new Http();
string requestUrl = $"https://{ServerAddress}/certificate/GetProv?vpkiType={certificate.TTbscsr.CCertType}";
var response = await ApiService.GetJsonAsync<string>(requestUrl);
var response = await http.GetJsonAsync<string>(requestUrl);
string fileName = $"SubCA.pem";
bool exportResult = await JS.InvokeAsync<bool>("openSaveFileStr", fileName, response);

View File

@ -8,7 +8,7 @@ using VPKI.Library.Services;
namespace VPKI.Web.Client.Services
{
public class ApiService : HttpService
public class ApiService
{
private readonly ProtectedLocalStorage _localStorage;
private readonly ConfigService<WebClientConfig> _configService;
@ -23,76 +23,12 @@ namespace VPKI.Web.Client.Services
_configService = configService;
}
public async Task<RESPONSE?> PostJsonAsyncBearer<REQUEST, RESPONSE>(string url, REQUEST request, short timeOutSeconds = 5) where REQUEST : class where RESPONSE : class
public async Task<string?> GetSessionState()
{
RESPONSE? response = default(RESPONSE);
Guid guid = Guid.NewGuid();
var sessionModel = (await _localStorage.GetAsync<LoginResponseModel>(SESSION_STATE)).Value;
var token = sessionModel?.AccessToken;
var apiConfig = _configService?.GetConfig()?.Api?.Find(x => x.ApiName?.ToLower() == Consts.VPKI_API.ToLower());
string apiUrl = $"{apiConfig.Address}:{apiConfig.Port}";
using (HttpClient httpClient = new HttpClient(GetClientHandler()))
{
try
{
//bearer token set
var sessionModel = (await _localStorage.GetAsync<LoginResponseModel>(SESSION_STATE)).Value;
var token = sessionModel?.AccessToken;
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $"{token}");
var timeOutSec = SetTimeout(timeOutSeconds);
httpClient.Timeout = new TimeSpan(0, 0, timeOutSec);
httpClient.BaseAddress = new Uri($"{apiUrl}{url}");
Log4net.WriteLine($"[POST] Request({guid})::{url}{Environment.NewLine}{request?.ToJson()}", LogType.HTTP);
var res = await httpClient.PostAsJsonAsync(url, request);
response = await res.Content.ReadFromJsonAsync<RESPONSE>();
Log4net.WriteLine($"[POST] Rseponse({guid})::{url}{Environment.NewLine}{response?.ToJson()}", LogType.HTTP);
}
catch (Exception e)
{
Log4net.WriteLine(e);
}
}
return response;
}
public async Task<RESPONSE?> GetJsonAsyncBearer<RESPONSE>(string url, short timeOutSeconds = 5) where RESPONSE : class
{
RESPONSE? response = default(RESPONSE);
Guid guid = Guid.NewGuid();
var apiConfig = _configService?.GetConfig()?.Api?.Find(x => x.ApiName?.ToLower() == Consts.VPKI_API.ToLower());
string apiUrl = $"{apiConfig.Address}:{apiConfig.Port}";
using (HttpClient httpClient = new HttpClient(GetClientHandler()))
{
try
{
//bearer token set
var sessionModel = (await _localStorage.GetAsync<LoginResponseModel>(SESSION_STATE)).Value;
var token = sessionModel?.AccessToken;
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $"{token}");
var timeOutSec = SetTimeout(timeOutSeconds);
httpClient.Timeout = new TimeSpan(0, 0, timeOutSec);
httpClient.BaseAddress = new Uri($"{apiUrl}{url}");
Log4net.WriteLine($"[GET] Request({guid})::{url}{Environment.NewLine}", LogType.HTTP);
var res = await httpClient.GetAsync(url);
response = await res.Content.ReadFromJsonAsync<RESPONSE>();
Log4net.WriteLine($"[GET] Rseponse({guid})::{url}{Environment.NewLine}{response?.ToJson()}", LogType.HTTP);
}
catch (Exception e)
{
Log4net.WriteLine(e);
}
}
return response;
return token;
}
}
}