Robert 1 жил өмнө
parent
commit
0e9a427747

+ 1 - 1
EVCB_OCPP.WSServer/Jobs/DenyModelCheckJob.cs

@@ -40,7 +40,7 @@ public class DenyModelCheckJob : IJob
         //logger.LogDebug("{0} Started", nameof(DenyModelCheckJob));
         try
         {
-            GlobalConfig.DenyModelNames = await webDbService.GetDenyModelNames();
+            GlobalConfig.DenyModelNames = await webDbService.GetDenyModelNames(context.CancellationToken);
             //logger.LogDebug("Current DenyList:[{0}]", string.Join(",", GlobalConfig.DenyModelNames));
 
             if (string.IsNullOrEmpty(GlobalConfig.DenyModelNames[0]))

+ 1 - 1
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -182,7 +182,7 @@ namespace EVCB_OCPP.WSServer
 
         public async Task StartAsync(CancellationToken cancellationToken)
         {
-            GlobalConfig.DenyModelNames = await webDbService.GetDenyModelNames();
+            GlobalConfig.DenyModelNames = await webDbService.GetDenyModelNames(cancellationToken);
             Start();
             return;
         }

+ 4 - 4
EVCB_OCPP.WSServer/Service/MainDbService.cs

@@ -92,7 +92,7 @@ public class MainDbService : IMainDbService
         using var semaphoreWrapper = await startupSemaphore.GetToken();
         using var db = await contextFactory.CreateDbContextAsync(token);
 
-        var machine = await db.Machine.Where(x => x.ChargeBoxId == ChargeBoxId && x.IsDelete == false).Select(x => new { x.CustomerId, x.Id }).AsNoTracking().FirstOrDefaultAsync();
+        var machine = await db.Machine.Where(x => x.ChargeBoxId == ChargeBoxId && x.IsDelete == false).Select(x => new { x.CustomerId, x.Id }).AsNoTracking().FirstOrDefaultAsync(token);
         if (machine == null)
         {
             return new MachineAndCustomerInfo(string.Empty, Guid.Empty, "Unknown");
@@ -106,10 +106,10 @@ public class MainDbService : IMainDbService
     public async Task<string> GetMachineConfiguration(string ChargeBoxId, string configName, CancellationToken token = default)
     {
         using var semaphoreWrapper = await startupSemaphore.GetToken();
-        using var db = await contextFactory.CreateDbContextAsync();
+        using var db = await contextFactory.CreateDbContextAsync(token);
         return await db.MachineConfigurations
             .Where(x => x.ChargeBoxId == ChargeBoxId && x.ConfigureName == configName)
-            .Select(x => x.ConfigureSetting).FirstOrDefaultAsync();
+            .Select(x => x.ConfigureSetting).FirstOrDefaultAsync(token);
     }
 
     public Task<string> GetMachineSecurityProfile(string ChargeBoxId, CancellationToken token = default)
@@ -663,7 +663,7 @@ public class MainDbService : IMainDbService
 
     private async Task BundleUpdateConnectorStatusDapper(BundleHandlerData<StatusNotificationParam> bundleHandlerData)
     {
-        using var conn = sqlConnectionFactory.Create();
+        using var conn = await sqlConnectionFactory.CreateAsync();
         foreach (var status in bundleHandlerData.Datas)
         {
             var parameters = new DynamicParameters();

+ 24 - 8
EVCB_OCPP.WSServer/Service/MapApiServce.cs

@@ -1,5 +1,6 @@
 using EVCB_OCPP.WSServer.Service.WsService;
 using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
 using NLog;
 using System;
 using System.Collections.Generic;
@@ -13,7 +14,10 @@ public static class MapApiServceExtention
 {
     public static void MapApiServce(this WebApplication webApplication)
     {
-        var helpFunc = () => {
+        var pass = webApplication.Configuration["apipass"];
+
+        var helpFunc = () =>
+        {
             return string.Join("\r\n", new[] {
                     "Command help!!",
                     "lcn : List Customer Name",
@@ -29,12 +33,12 @@ public static class MapApiServceExtention
         webApplication.MapPost("/stop", (ProtalServer server) => {
             server.Stop();
             return "Command stop";
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapPost("/gc", () => {
             GC.Collect();
             return "Command GC";
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapPost("/lc", (ProtalServer server) => {
             List<string> toReturn = new List<string>() { "Command List Clients" };
@@ -47,7 +51,7 @@ public static class MapApiServceExtention
                 i++;
             }
             return string.Join("\r\n", toReturn);
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapPost("/lcn", (ProtalServer server) => {
             List<string> toReturn = new List<string> { "Command List Customer Name" };
@@ -60,7 +64,7 @@ public static class MapApiServceExtention
                 iLcn++;
             }
             return string.Join("\r\n", toReturn);
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapPost("/silent", () => {
             foreach (var rule in LogManager.Configuration.LoggingRules)
@@ -78,7 +82,7 @@ public static class MapApiServceExtention
                 }
             }
             return "Command silent";
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapPost("/show", () => {
             foreach (var rule in LogManager.Configuration.LoggingRules)
@@ -96,13 +100,13 @@ public static class MapApiServceExtention
                 }
             }
             return "Command show";
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapGet("/threads", () => {
             ThreadPool.GetMaxThreads(out var maxWorkerThread, out var maxCompletionPortThreads);
             ThreadPool.GetAvailableThreads(out var avaliableWorkerThread, out var avaliableCompletionPortThreads);
             return $"WorkerThread:{avaliableWorkerThread}/{maxWorkerThread} CompletionPortThreads{avaliableCompletionPortThreads}/{maxCompletionPortThreads}";
-        });
+        }).AddAuthFilter(pass);
 
         webApplication.MapPost("/threads", (int min, int max) => {
             ThreadPool.GetMaxThreads(out var maxWorkerThread, out var maxCompletionPortThreads);
@@ -110,6 +114,18 @@ public static class MapApiServceExtention
             ThreadPool.SetMinThreads(min, 0);
             ThreadPool.SetMaxThreads(max, maxCompletionPortThreads);
             return $"WorkerThread:{avaliableWorkerThread}/{maxWorkerThread} CompletionPortThreads{avaliableCompletionPortThreads}/{maxCompletionPortThreads}";
+        }).AddAuthFilter(pass);
+    }
+
+    public static void AddAuthFilter(this RouteHandlerBuilder routeHandlerBuilder, string pass)
+    {
+        routeHandlerBuilder.AddEndpointFilter(async (context, next) => {
+            var key = context.HttpContext.Request.Headers["key"];
+            if (key != pass)
+            {
+                return Results.BadRequest();
+            }
+            return await next(context);
         });
     }
 }

+ 4 - 2
EVCB_OCPP.WSServer/Service/WebDbService.cs

@@ -23,7 +23,7 @@ public class WebDbService
 
     //private readonly string webConnectionString;
 
-    public async Task<List<string>> GetDenyModelNames()
+    public async Task<List<string>> GetDenyModelNames(CancellationToken token = default)
     {
         using SqlConnection conn = await webDbConnectionFactory.CreateAsync();
         string strSql = """
@@ -32,7 +32,9 @@ public class WebDbService
                 where SystemKey = 'DenyModelNames';
                 """;
 
-        var result = await conn.QueryFirstOrDefaultAsync<string>(strSql);
+        var result = await conn.QueryFirstOrDefaultAsync<string>(
+            new CommandDefinition(strSql, cancellationToken: token)
+            );
 
         return result.Split(',').ToList();
 

+ 37 - 27
EVCB_OCPP.WSServer/Service/WsService/OcppWebsocketService.cs

@@ -165,7 +165,16 @@ public class OcppWebsocketService : WebsocketService<WsClientData>
         //                  .Select(x => x.ConfigureSetting).FirstOrDefault();
         var configVaule = await mainDbService.GetMachineSecurityProfile(session.ChargeBoxId, context.RequestAborted);
         if (context.RequestAborted.IsCancellationRequested) return false;
-        int.TryParse(configVaule, out securityProfile);
+        if (string.IsNullOrEmpty(configVaule))
+        {
+            return true;
+        }
+
+        if (!int.TryParse(configVaule, out securityProfile))
+        {
+            logger.LogCritical("ERROR securityProfile setted {securityProfile}", configVaule);
+            return false;
+        }
 
         if (session.ISOCPP20)
         {
@@ -184,43 +193,44 @@ public class OcppWebsocketService : WebsocketService<WsClientData>
         {
             if (securityProfile == 2 && session.UriScheme == "ws")
             {
-                authorizated = false;
+                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
+                logger.LogTrace("{id} {func} {Statuscode}", context.TraceIdentifier, nameof(ValidateHandshake), context.Response.StatusCode);
+                return false;
             }
 
             //if (session.Items.ContainsKey("Authorization") || session.Items.ContainsKey("authorization"))
-            if (!string.IsNullOrEmpty(authHeader))
+            if (string.IsNullOrEmpty(authHeader))
             {
-                //authorizationKey = db.MachineConfigurations.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.AuthorizationKey)
-                //                    .Select(x => x.ConfigureSetting).FirstOrDefault();
-                authorizationKey = await mainDbService.GetMachineAuthorizationKey(session.ChargeBoxId, context.RequestAborted);
-                if (context.RequestAborted.IsCancellationRequested) return false;
+                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
+                logger.LogTrace("{id} {func} {Statuscode}", context.TraceIdentifier, nameof(ValidateHandshake), context.Response.StatusCode);
+                return false;
+            }
+            //authorizationKey = db.MachineConfigurations.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.AuthorizationKey)
+            //                    .Select(x => x.ConfigureSetting).FirstOrDefault();
+            authorizationKey = await mainDbService.GetMachineAuthorizationKey(session.ChargeBoxId, context.RequestAborted);
+            if (context.RequestAborted.IsCancellationRequested) return false;
 
-                if (session.ISOCPP20)
-                {
-                    // 1.6 server only support change server  function
-                    securityProfile = 0;
-                }
+            if (session.ISOCPP20)
+            {
+                // 1.6 server only support change server  function
+                securityProfile = 0;
+            }
 
-                logger.LogInformation("{id} ***********Authorization   ", context.TraceIdentifier);
+            logger.LogInformation("{id} ***********Authorization   ", context.TraceIdentifier);
 
-                if (!string.IsNullOrEmpty(authorizationKey))
+            if (!string.IsNullOrEmpty(authorizationKey))
+            {
+                //string base64Encoded = session.Items.ContainsKey("Authorization") ? session.Items["Authorization"].ToString().Replace("Basic ", "") : session.Items["authorization"].ToString().Replace("Basic ", "");
+                string base64Encoded = authHeader.Replace("Basic ", "");
+                byte[] data = Convert.FromBase64String(base64Encoded);
+                string[] base64Decoded = Encoding.ASCII.GetString(data).Split(':');
+                logger.LogInformation("{id} ***********Authorization   " + Encoding.ASCII.GetString(data), context.TraceIdentifier);
+                if (base64Decoded.Count() == 2 && base64Decoded[0] == session.ChargeBoxId && base64Decoded[1] == authorizationKey)
                 {
-                    //string base64Encoded = session.Items.ContainsKey("Authorization") ? session.Items["Authorization"].ToString().Replace("Basic ", "") : session.Items["authorization"].ToString().Replace("Basic ", "");
-                    string base64Encoded = authHeader.Replace("Basic ", "");
-                    byte[] data = Convert.FromBase64String(base64Encoded);
-                    string[] base64Decoded = Encoding.ASCII.GetString(data).Split(':');
-                    logger.LogInformation("{id} ***********Authorization   " + Encoding.ASCII.GetString(data), context.TraceIdentifier);
-                    if (base64Decoded.Count() == 2 && base64Decoded[0] == session.ChargeBoxId && base64Decoded[1] == authorizationKey)
-                    {
-                        authorizated = true;
-                    }
+                    authorizated = true;
                 }
             }
-            else
-            {
-                authorizated = true;
 
-            }
 
             if (!authorizated)
             {

+ 1 - 26
EVCB_OCPP.WSServer/appsettings.json

@@ -2,36 +2,11 @@
   "WSPort": 54089,
   "WSSPort": "",
   "LocalAuthAPI": "",
+  "apipass": "12345678",
   "LogProvider": "NLog",
   "OCPP20_WSUrl": "ws://ocpp.phihong.com.tw:5004",
   "OCPP20_WSSUrl": "ws://ocpp.phihong.com.tw:5004",
   "MaintainMode": 0,
-  "superSocket": {
-    "Servers": [
-      {
-        "Name": "SuperWebSocket",
-        "serverTypeName": "SuperWebSocket",
-        "Certificate": {
-          "filePath": "localhost.pfx",
-          "password": "supersocket",
-          "storeName": "My",
-          "thumbprint": "‎3f07fb28c158843209db8f51bfe748dbe9f52399",
-          "storeLocation": "LocalMachine",
-          "clientCertificateRequired": "false",
-          "keyStorageFlags": "Exportable"
-        }
-      }
-    ]
-  },
-  "SuperSocketServerCertificate": {
-    "filePath": "localhost.pfx",
-    "password": "supersocket",
-    "storeName": "My",
-    "thumbprint": "‎3f07fb28c158843209db8f51bfe748dbe9f52399",
-    "storeLocation": "LocalMachine",
-    "clientCertificateRequired": "false",
-    "keyStorageFlags": "Exportable"
-  },
   "Logging": {
     "LogLevel": {
       "Default": "Information",