✨ Authenticate.

Signed-off-by: 秋雨落 <i@rain.cx>
This commit is contained in:
秋雨落
2023-09-14 15:15:45 +08:00
parent 185b231e7d
commit cf814e05fc
9 changed files with 86 additions and 20 deletions
@@ -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<bool>("Connector:Debug");
}
public string GetSecretKey()
{
return Config.GetValue<string>("Connector:Auth:Secret") ?? "";
}
}
@@ -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)
{
}
}
@@ -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);
}
}
@@ -2,7 +2,9 @@
public class HandlerConstants public class HandlerConstants
{ {
public static readonly string MessageTypeAuthenticate = "Authenticate"; public static readonly string OperationAuthenticate = "Authenticate";
public static readonly string MessageTypeRegisterHandler = "Register"; public static readonly string OperationRegisterChannel = "Register";
public static readonly string MessageTypeEmit = "Emit"; public static readonly string OperationPublish = "Publish";
public static readonly string ResponseAuthenticated = "Authenticated";
} }
+10 -8
View File
@@ -1,37 +1,39 @@
using System.Formats.Cbor; using System.Formats.Cbor;
using System.Net.WebSockets; using System.Net.WebSockets;
using CrystalConnector.Configs;
using CrystalConnector.Connector.Packet;
using CrystalConnector.Utilities; using CrystalConnector.Utilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace CrystalConnector.Handlers; namespace CrystalConnector.Handlers;
public class WebSocketHandler public class WebSocketHandler
{ {
private IConfiguration Config { get; } private ConfigAccessor Config { get; }
private ILogger<WebSocketHandler> Logger { get; } private ILogger<WebSocketHandler> Logger { get; }
public WebSocketHandler(IConfiguration config, ILogger<WebSocketHandler> logger) public WebSocketHandler(ConfigAccessor config, ILogger<WebSocketHandler> logger)
{ {
Config = config; Config = config;
Logger = logger; Logger = logger;
} }
public void Handle(WebSocket webSocket, CborReader reader) public async Task Handle(WebSocket webSocket, CborReader reader)
{ {
reader.ReadStartArray(); reader.ReadStartArray();
var type = reader.ReadTextString(); var type = reader.ReadTextString();
if (type == HandlerConstants.MessageTypeAuthenticate) if (type == HandlerConstants.OperationAuthenticate)
{ {
if (!webSocket.GetConnectionInfo().Authorized) if (!webSocket.GetConnectionInfo().Authenticated)
{ {
var secret = reader.ReadTextString(); var secret = reader.ReadTextString();
if (secret == Config.GetValue<string>("Connector:Auth:Secret")) if (secret == Config.GetSecretKey())
{ {
Logger.LogInformation("Client {Id} authorized", webSocket.GetConnectionInfo().Id); Logger.LogInformation("Client {Id} authorized", webSocket.GetConnectionInfo().Id);
webSocket.GetConnectionInfo().Authorized = true; webSocket.GetConnectionInfo().Authenticated = true;
await webSocket.Send(new S2CAuthenticatedPacket().Write);
} }
else else
{ {
+2
View File
@@ -1,6 +1,7 @@
using System.Net; using System.Net;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using CrystalConnector; using CrystalConnector;
using CrystalConnector.Configs;
using CrystalConnector.Handlers; using CrystalConnector.Handlers;
using CrystalConnector.WebSockets; using CrystalConnector.WebSockets;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
@@ -95,4 +96,5 @@ void ConfigureServices(IServiceCollection services)
{ {
services.AddSingleton<IWebSocketManager, WebSocketManager>(); services.AddSingleton<IWebSocketManager, WebSocketManager>();
services.AddSingleton<WebSocketHandler>(); services.AddSingleton<WebSocketHandler>();
services.AddSingleton<ConfigAccessor>();
} }
@@ -11,7 +11,9 @@ public class WebSocketConnectionInfo
public required TaskCompletionSource<WebSocketHandleResult> CompletionSource { get; set; } public required TaskCompletionSource<WebSocketHandleResult> CompletionSource { get; set; }
public bool Authorized { get; set; } = false; public string? Name { get; set; }
public bool Authenticated { get; set; } = false;
public List<MessageChannel> RegisteredChannels { get; } = new(); public List<MessageChannel> RegisteredChannels { get; } = new();
} }
@@ -1,4 +1,5 @@
using System.Net; using System.Formats.Cbor;
using System.Net;
using System.Net.WebSockets; using System.Net.WebSockets;
using CrystalConnector.Connector; using CrystalConnector.Connector;
@@ -32,6 +33,15 @@ public static class WebSocketExtension
WebSocketConnectionManager.Info.Remove(webSocket); WebSocketConnectionManager.Info.Remove(webSocket);
} }
public static async Task Send(this WebSocket webSocket, Action<CborWriter> 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) public static async Task Send(this WebSocket webSocket, byte[] data)
{ {
await webSocket.Send(data, 0, data.Length); await webSocket.Send(data, 0, data.Length);
@@ -1,10 +1,10 @@
using System.Formats.Cbor; using System.Formats.Cbor;
using System.Net; using System.Net;
using System.Net.WebSockets; using System.Net.WebSockets;
using CrystalConnector.Configs;
using CrystalConnector.Handlers; using CrystalConnector.Handlers;
using CrystalConnector.Utilities; using CrystalConnector.Utilities;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace CrystalConnector.WebSockets; namespace CrystalConnector.WebSockets;
@@ -13,11 +13,11 @@ public class WebSocketManager : IWebSocketManager
{ {
private ILogger<WebSocketManager> Logger { get; } private ILogger<WebSocketManager> Logger { get; }
private IConfiguration Config { get; } private ConfigAccessor Config { get; }
private WebSocketHandler Handler { get; } private WebSocketHandler Handler { get; }
public WebSocketManager(ILogger<WebSocketManager> logger, IConfiguration config, WebSocketHandler handler) public WebSocketManager(ILogger<WebSocketManager> logger, ConfigAccessor config, WebSocketHandler handler)
{ {
Logger = logger; Logger = logger;
Config = config; Config = config;
@@ -42,20 +42,19 @@ public class WebSocketManager : IWebSocketManager
try try
{ {
Handler.Handle(webSocket, reader); await Handler.Handle(webSocket, reader);
} }
catch (CborContentException ex) catch (CborContentException ex)
{ {
if (Config.GetValue<bool>("Connector:Debug")) if (Config.IsDebug())
{ {
Logger.LogWarning(ex, "Malformed message!"); Logger.LogWarning(ex, "Malformed message!");
} }
Disconnect(webSocket); Disconnect(webSocket);
} }
catch (InvalidOperationException ex) catch (InvalidOperationException ex)
{ {
if (Config.GetValue<bool>("Connector:Debug")) if (Config.IsDebug())
{ {
Logger.LogWarning(ex, "Bad message!"); Logger.LogWarning(ex, "Bad message!");
} }