From f5456f3356d55de8c35bfa38082af6fabb145409 Mon Sep 17 00:00:00 2001 From: Young Date: Thu, 3 Oct 2024 10:16:00 +0800 Subject: [PATCH] added security --- .../Security/DefaultAuthenticationHandler.cs | 38 ++++++++++++++ .../Security/IEncryptionService.cs | 50 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/Infrastructure/Security/DefaultAuthenticationHandler.cs create mode 100644 src/Infrastructure/Security/IEncryptionService.cs diff --git a/src/Infrastructure/Security/DefaultAuthenticationHandler.cs b/src/Infrastructure/Security/DefaultAuthenticationHandler.cs new file mode 100644 index 0000000..3313bb9 --- /dev/null +++ b/src/Infrastructure/Security/DefaultAuthenticationHandler.cs @@ -0,0 +1,38 @@ +using System.Text.Encodings.Web; +using Infrastructure.Utils; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Infrastructure.Security; + +public class DefaultAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder) + : AuthenticationHandler(options, logger, encoder) +{ + private const string Message = "You are not authorized to access this resource"; + + protected override Task HandleAuthenticateAsync() + { + throw new NotImplementedException(); + } + + protected override async Task HandleForbiddenAsync(AuthenticationProperties properties) + { + Response.ContentType = "application/json"; + Response.StatusCode = StatusCodes.Status200OK; + await Response.WriteAsync(new MessageData(false, Message, 403) + .Serialize()); + } + + protected override async Task HandleChallengeAsync(AuthenticationProperties properties) + { + Response.ContentType = "application/json"; + Response.StatusCode = StatusCodes.Status200OK; + await Response.WriteAsync(new MessageData(false,Message, 401) + .Serialize()); + } +} \ No newline at end of file diff --git a/src/Infrastructure/Security/IEncryptionService.cs b/src/Infrastructure/Security/IEncryptionService.cs new file mode 100644 index 0000000..9eeda16 --- /dev/null +++ b/src/Infrastructure/Security/IEncryptionService.cs @@ -0,0 +1,50 @@ +using System.Text; +using Microsoft.Extensions.Configuration; +using System.Security.Cryptography; + +namespace Infrastructure.Security; + +public interface IEncryptionService +{ + string Encrypt(string plain, string? aesKey = null); + + string Decrypt(string cipher, string? aesKey = null); +} + +public class EncryptionService(IConfiguration configuration) : IEncryptionService +{ + public string Encrypt(string plain, string? aesKey = null) + { + ArgumentException.ThrowIfNullOrEmpty(plain); + using var aes = CreateAes(aesKey); + using var encryptor = aes.CreateEncryptor(); + var plainTextArray = Encoding.UTF8.GetBytes(plain); + var resultArray = encryptor.TransformFinalBlock(plainTextArray, 0, plainTextArray.Length); + var result = Convert.ToBase64String(resultArray); + Array.Clear(resultArray); + return result; + } + + public string Decrypt(string cipher, string? aesKey = null) + { + ArgumentException.ThrowIfNullOrEmpty(cipher); + using var aes = CreateAes(aesKey); + using var decryptor = aes.CreateDecryptor(); + var cipherTextArray = Convert.FromBase64String(cipher); + var resultArray = decryptor.TransformFinalBlock(cipherTextArray, 0, cipherTextArray.Length); + var result = Encoding.UTF8.GetString(resultArray); + Array.Clear(resultArray); + return result; + } + + private Aes CreateAes(string? aesKey) + { + var aes = Aes.Create(); + aes.Mode = CipherMode.ECB; + aes.Padding = PaddingMode.PKCS7; + var key = aesKey ?? configuration["AES_KEY"]; + ArgumentException.ThrowIfNullOrEmpty(key); + aes.Key = MD5.HashData(Encoding.UTF8.GetBytes(key)); + return aes; + } +} \ No newline at end of file