From ae5ab1492ed2b5c81c8469a2fdb899aed16dbb2b Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Wed, 13 May 2026 22:05:04 +0330 Subject: [PATCH] fix: update gRPC service configuration to use CmsServerBaseUrl resolver - Replace direct access to configuration for GwUrl with CmsServerBaseUrl.Resolve in AddGrpcServices and TokenNotificationService. - Ensure proper error handling for missing GwUrl and add support for optional bypass of public TLS using CmsInternalBaseUrl. - Adjust channel credentials based on whether the base URL is HTTPS or not. --- k8s/staging/frontoffice-deployment.yaml | 59 +++++++++++++++++++ src/FrontOffice.Main/ConfigureServices.cs | 13 +++- .../Utilities/CmsServerBaseUrl.cs | 18 ++++++ .../Utilities/TokenNotificationService.cs | 2 +- 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 k8s/staging/frontoffice-deployment.yaml create mode 100644 src/FrontOffice.Main/Utilities/CmsServerBaseUrl.cs diff --git a/k8s/staging/frontoffice-deployment.yaml b/k8s/staging/frontoffice-deployment.yaml new file mode 100644 index 0000000..bfcb1d1 --- /dev/null +++ b/k8s/staging/frontoffice-deployment.yaml @@ -0,0 +1,59 @@ +--- +# FrontOffice (Blazor Server) — staging. Server-side gRPC/SignalR to CMS: set CmsInternalBaseUrl to the +# in-cluster Service URL so TLS is not terminated on a broken public chain (PartialChain). +apiVersion: apps/v1 +kind: Deployment +metadata: + name: frontoffice + namespace: default + labels: + app: frontoffice + environment: staging +spec: + replicas: 1 + selector: + matchLabels: + app: frontoffice + template: + metadata: + labels: + app: frontoffice + spec: + containers: + - name: frontoffice + image: 194.5.195.53:30080/admin/frontoffice:latest + imagePullPolicy: Always + ports: + - containerPort: 80 + name: http + env: + - name: ASPNETCORE_ENVIRONMENT + value: "Staging" + - name: CmsInternalBaseUrl + value: "http://cms-svc:8080" + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + imagePullSecrets: + - name: gitea-registry-secret + +--- +apiVersion: v1 +kind: Service +metadata: + name: frontoffice-svc + namespace: default + labels: + app: frontoffice +spec: + selector: + app: frontoffice + ports: + - port: 80 + targetPort: 80 + name: http + type: ClusterIP diff --git a/src/FrontOffice.Main/ConfigureServices.cs b/src/FrontOffice.Main/ConfigureServices.cs index fa7c3f9..ca67e8c 100644 --- a/src/FrontOffice.Main/ConfigureServices.cs +++ b/src/FrontOffice.Main/ConfigureServices.cs @@ -100,7 +100,9 @@ public static class ConfigureServices public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration) { - var baseUrl = configuration["GwUrl"]; + var baseUrl = CmsServerBaseUrl.Resolve(configuration) + ?? throw new InvalidOperationException( + "GwUrl is required. Optionally set CmsInternalBaseUrl (e.g. http://cms-svc:8080 on Kubernetes) to bypass public TLS for server-side gRPC."); // Register optimized HttpClient for gRPC services.AddScoped(sp => @@ -158,6 +160,7 @@ public static class ConfigureServices var httpClient = sp.GetRequiredService(); var localStorage = sp.GetRequiredService(); var baseUrl = httpClient.BaseAddress?.ToString() ?? throw new InvalidOperationException("Base URL not configured"); + var isHttps = baseUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase); var credentials = CallCredentials.FromInterceptor(async (context, metadata) => { @@ -177,10 +180,14 @@ public static class ConfigureServices } }); + var channelCredentials = isHttps + ? ChannelCredentials.Create(new SslCredentials(), credentials) + : ChannelCredentials.Create(ChannelCredentials.Insecure, credentials); + var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { - UnsafeUseInsecureChannelCallCredentials = true, - Credentials = ChannelCredentials.Create(new SslCredentials(), credentials), + UnsafeUseInsecureChannelCallCredentials = !isHttps, + Credentials = channelCredentials, HttpClient = httpClient, MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB diff --git a/src/FrontOffice.Main/Utilities/CmsServerBaseUrl.cs b/src/FrontOffice.Main/Utilities/CmsServerBaseUrl.cs new file mode 100644 index 0000000..e7eb431 --- /dev/null +++ b/src/FrontOffice.Main/Utilities/CmsServerBaseUrl.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.Configuration; + +namespace FrontOffice.Main.Utilities; + +/// +/// Server-side base URL for CMS (gRPC-Web, SignalR). Prefer in-cluster HTTP when FrontOffice runs on Kubernetes +/// next to CMS to avoid public ingress TLS chain issues (e.g. PartialChain). +/// +public static class CmsServerBaseUrl +{ + public static string? Resolve(IConfiguration configuration) + { + var internalUrl = configuration["CmsInternalBaseUrl"]; + if (!string.IsNullOrWhiteSpace(internalUrl)) + return internalUrl.TrimEnd('/'); + return configuration["GwUrl"]?.TrimEnd('/'); + } +} diff --git a/src/FrontOffice.Main/Utilities/TokenNotificationService.cs b/src/FrontOffice.Main/Utilities/TokenNotificationService.cs index 7912dc6..c4cd4f8 100644 --- a/src/FrontOffice.Main/Utilities/TokenNotificationService.cs +++ b/src/FrontOffice.Main/Utilities/TokenNotificationService.cs @@ -69,7 +69,7 @@ public class TokenNotificationService : IAsyncDisposable return; } - var gwUrl = _configuration["GwUrl"]?.TrimEnd('/') ?? "https://localhost:5002"; + var gwUrl = CmsServerBaseUrl.Resolve(_configuration) ?? "https://localhost:5002"; var hubPath = _configuration["SignalR:HubPath"] ?? "/hubs/token-relay"; var hubUrl = $"{gwUrl}{hubPath}";