From cf814e05fca28f8b37614e5e1f883b2cb2de3c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E9=9B=A8=E8=90=BD?= Date: Thu, 14 Sep 2023 15:15:45 +0800 Subject: [PATCH] :sparkles: Authenticate. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 秋雨落 --- CrystalConnector/Configs/ConfigAccessor.cs | 23 +++++++++++++++++++ CrystalConnector/Connector/Packet/IPacket.cs | 14 +++++++++++ .../Packet/S2CAuthenticatedPacket.cs | 12 ++++++++++ CrystalConnector/Handlers/HandlerConstants.cs | 8 ++++--- CrystalConnector/Handlers/WebSocketHandler.cs | 18 ++++++++------- CrystalConnector/Program.cs | 2 ++ .../Utilities/WebSocketConnectionInfo.cs | 4 +++- .../Utilities/WebSocketExtension.cs | 12 +++++++++- .../WebSockets/WebSocketManager.cs | 13 +++++------ 9 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 CrystalConnector/Configs/ConfigAccessor.cs create mode 100644 CrystalConnector/Connector/Packet/IPacket.cs create mode 100644 CrystalConnector/Connector/Packet/S2CAuthenticatedPacket.cs diff --git a/CrystalConnector/Configs/ConfigAccessor.cs b/CrystalConnector/Configs/ConfigAccessor.cs new file mode 100644 index 0000000..b048812 --- /dev/null +++ b/CrystalConnector/Configs/ConfigAccessor.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Configuration; + +namespace CrystalConnector.Configs; + +public class ConfigAccessor +{ + private IConfiguration Config { get; } + + public ConfigAccessor(IConfiguration config) + { + Config = config; + } + + public bool IsDebug() + { + return Config.GetValue("Connector:Debug"); + } + + public string GetSecretKey() + { + return Config.GetValue("Connector:Auth:Secret") ?? ""; + } +} \ No newline at end of file diff --git a/CrystalConnector/Connector/Packet/IPacket.cs b/CrystalConnector/Connector/Packet/IPacket.cs new file mode 100644 index 0000000..8a85d43 --- /dev/null +++ b/CrystalConnector/Connector/Packet/IPacket.cs @@ -0,0 +1,14 @@ +using System.Formats.Cbor; + +namespace CrystalConnector.Connector.Packet; + +public interface IPacket +{ + public void Write(CborWriter writer) + { + } + + public void Read(CborReader reader) + { + } +} \ No newline at end of file diff --git a/CrystalConnector/Connector/Packet/S2CAuthenticatedPacket.cs b/CrystalConnector/Connector/Packet/S2CAuthenticatedPacket.cs new file mode 100644 index 0000000..ce27749 --- /dev/null +++ b/CrystalConnector/Connector/Packet/S2CAuthenticatedPacket.cs @@ -0,0 +1,12 @@ +using System.Formats.Cbor; +using CrystalConnector.Handlers; + +namespace CrystalConnector.Connector.Packet; + +public class S2CAuthenticatedPacket : IPacket +{ + public void Write(CborWriter writer) + { + writer.WriteTextString(HandlerConstants.ResponseAuthenticated); + } +} \ No newline at end of file diff --git a/CrystalConnector/Handlers/HandlerConstants.cs b/CrystalConnector/Handlers/HandlerConstants.cs index 24b8bd5..e0bf396 100644 --- a/CrystalConnector/Handlers/HandlerConstants.cs +++ b/CrystalConnector/Handlers/HandlerConstants.cs @@ -2,7 +2,9 @@ public class HandlerConstants { - public static readonly string MessageTypeAuthenticate = "Authenticate"; - public static readonly string MessageTypeRegisterHandler = "Register"; - public static readonly string MessageTypeEmit = "Emit"; + public static readonly string OperationAuthenticate = "Authenticate"; + public static readonly string OperationRegisterChannel = "Register"; + public static readonly string OperationPublish = "Publish"; + + public static readonly string ResponseAuthenticated = "Authenticated"; } \ No newline at end of file diff --git a/CrystalConnector/Handlers/WebSocketHandler.cs b/CrystalConnector/Handlers/WebSocketHandler.cs index 0f3ef15..49ed00d 100644 --- a/CrystalConnector/Handlers/WebSocketHandler.cs +++ b/CrystalConnector/Handlers/WebSocketHandler.cs @@ -1,37 +1,39 @@ using System.Formats.Cbor; using System.Net.WebSockets; +using CrystalConnector.Configs; +using CrystalConnector.Connector.Packet; using CrystalConnector.Utilities; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace CrystalConnector.Handlers; public class WebSocketHandler { - private IConfiguration Config { get; } + private ConfigAccessor Config { get; } private ILogger Logger { get; } - public WebSocketHandler(IConfiguration config, ILogger logger) + public WebSocketHandler(ConfigAccessor config, ILogger logger) { Config = config; Logger = logger; } - public void Handle(WebSocket webSocket, CborReader reader) + public async Task Handle(WebSocket webSocket, CborReader reader) { reader.ReadStartArray(); var type = reader.ReadTextString(); - if (type == HandlerConstants.MessageTypeAuthenticate) + if (type == HandlerConstants.OperationAuthenticate) { - if (!webSocket.GetConnectionInfo().Authorized) + if (!webSocket.GetConnectionInfo().Authenticated) { var secret = reader.ReadTextString(); - if (secret == Config.GetValue("Connector:Auth:Secret")) + if (secret == Config.GetSecretKey()) { Logger.LogInformation("Client {Id} authorized", webSocket.GetConnectionInfo().Id); - webSocket.GetConnectionInfo().Authorized = true; + webSocket.GetConnectionInfo().Authenticated = true; + await webSocket.Send(new S2CAuthenticatedPacket().Write); } else { diff --git a/CrystalConnector/Program.cs b/CrystalConnector/Program.cs index be6366b..204593f 100644 --- a/CrystalConnector/Program.cs +++ b/CrystalConnector/Program.cs @@ -1,6 +1,7 @@ using System.Net; using System.Security.Cryptography.X509Certificates; using CrystalConnector; +using CrystalConnector.Configs; using CrystalConnector.Handlers; using CrystalConnector.WebSockets; using Microsoft.AspNetCore.Hosting; @@ -95,4 +96,5 @@ void ConfigureServices(IServiceCollection services) { services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); } diff --git a/CrystalConnector/Utilities/WebSocketConnectionInfo.cs b/CrystalConnector/Utilities/WebSocketConnectionInfo.cs index 24895ca..11ef6b6 100644 --- a/CrystalConnector/Utilities/WebSocketConnectionInfo.cs +++ b/CrystalConnector/Utilities/WebSocketConnectionInfo.cs @@ -11,7 +11,9 @@ public class WebSocketConnectionInfo public required TaskCompletionSource CompletionSource { get; set; } - public bool Authorized { get; set; } = false; + public string? Name { get; set; } + + public bool Authenticated { get; set; } = false; public List RegisteredChannels { get; } = new(); } \ No newline at end of file diff --git a/CrystalConnector/Utilities/WebSocketExtension.cs b/CrystalConnector/Utilities/WebSocketExtension.cs index cda35c5..1a2cd97 100644 --- a/CrystalConnector/Utilities/WebSocketExtension.cs +++ b/CrystalConnector/Utilities/WebSocketExtension.cs @@ -1,4 +1,5 @@ -using System.Net; +using System.Formats.Cbor; +using System.Net; using System.Net.WebSockets; using CrystalConnector.Connector; @@ -32,6 +33,15 @@ public static class WebSocketExtension WebSocketConnectionManager.Info.Remove(webSocket); } + public static async Task Send(this WebSocket webSocket, Action write) + { + var writer = new CborWriter(); + writer.WriteStartArray(null); + write(writer); + writer.WriteEndArray(); + await webSocket.Send(writer.Encode()); + } + public static async Task Send(this WebSocket webSocket, byte[] data) { await webSocket.Send(data, 0, data.Length); diff --git a/CrystalConnector/WebSockets/WebSocketManager.cs b/CrystalConnector/WebSockets/WebSocketManager.cs index a847a19..b686046 100644 --- a/CrystalConnector/WebSockets/WebSocketManager.cs +++ b/CrystalConnector/WebSockets/WebSocketManager.cs @@ -1,10 +1,10 @@ using System.Formats.Cbor; using System.Net; using System.Net.WebSockets; +using CrystalConnector.Configs; using CrystalConnector.Handlers; using CrystalConnector.Utilities; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace CrystalConnector.WebSockets; @@ -13,11 +13,11 @@ public class WebSocketManager : IWebSocketManager { private ILogger Logger { get; } - private IConfiguration Config { get; } + private ConfigAccessor Config { get; } private WebSocketHandler Handler { get; } - public WebSocketManager(ILogger logger, IConfiguration config, WebSocketHandler handler) + public WebSocketManager(ILogger logger, ConfigAccessor config, WebSocketHandler handler) { Logger = logger; Config = config; @@ -42,20 +42,19 @@ public class WebSocketManager : IWebSocketManager try { - Handler.Handle(webSocket, reader); + await Handler.Handle(webSocket, reader); } catch (CborContentException ex) { - if (Config.GetValue("Connector:Debug")) + if (Config.IsDebug()) { Logger.LogWarning(ex, "Malformed message!"); } - Disconnect(webSocket); } catch (InvalidOperationException ex) { - if (Config.GetValue("Connector:Debug")) + if (Config.IsDebug()) { Logger.LogWarning(ex, "Bad message!"); }