Compare commits

...

9 Commits

Author SHA1 Message Date
Developer 02
ae28159562 Bump version to 1.2.0 in DigitalData.Auth.API.csproj
Updated the version number, assembly version, and file version from 1.1.2 to 1.2.0 in the project file, reflecting a new release of the software.
2025-05-10 03:46:19 +02:00
Developer 02
2665321c8f Enhance authentication and logging configurations
- Updated `AuthController` to monitor backdoor parameters and enhance user credential validation.
- Changed route for `Hash` method in `CryptController` for clarity.
- Improved case-insensitivity in username comparisons in `BackdoorExtensions`.
- Modified logging setup in `Program.cs` to clear providers and set minimum level to Trace.
- Added separate logging configuration for warnings in `appsettings.json`.
- Restructured `backdoors.json` to encapsulate entries within `BackdoorParams`.
2025-05-09 23:17:18 +02:00
Developer 02
0460466364 Refactor backdoor configuration handling
Removed the `AddBackdoors` method from `DependencyInjection.cs` and replaced its usage in `Program.cs` with `Configure<Backdoor>`. Updated `using` directives to include `Microsoft.Extensions.DependencyInjection`. Added a new `BackdoorParams` class to encapsulate backdoor configuration settings.
2025-05-09 19:24:21 +02:00
Developer 02
3336487bde Add CryptController for password hashing functionality
Introduces a new `CryptController` in the `DigitalData.Auth.API.Controllers` namespace. This API controller features a GET endpoint, `Hash`, which accepts a password as a query parameter and returns its BCrypt hashed version.
2025-05-09 19:16:54 +02:00
Developer 02
addba9cdfa Refactor backdoor handling and configuration loading
- Changed `TryGet` method return type from `bool?` to `bool` in `BackdoorExtensions.cs` for improved clarity.
- Updated configuration retrieval in `DependencyInjection.cs` to use `GetSection("backdoors")` for targeted loading.
- Added `backdoors.json` configuration file in `Program.cs` to enhance modularity and organization of settings.
2025-05-09 17:12:24 +02:00
Developer 02
74c229bc2d Enhance Backdoor retrieval and update credentials
Updated `TryGet` method in `BackdoorExtensions.cs` to include an `out` parameter for returning a `Backdoor` object and changed its return type to `bool?`. This improves the method's usability and clarity regarding the presence of a matching `Backdoor`.

Modified `backdoors.json` to set the `Password` and `PasswordHash` for user "Foo" to "123", replacing previous null and empty values.
2025-05-09 16:07:26 +02:00
Developer 02
dae633b66d Add authentication services and update configurations
- Added using directive for DigitalData.Auth.API.Models.
- Removed obsolete service configuration line.
- Introduced new service registrations: AddBackdoors, AddAuthService, and AddRSAPool.
- Retained configuration for AuthApiParams to ensure settings are utilized.
2025-05-09 15:42:47 +02:00
Developer 02
c3794f1e65 Enhance authentication features and dependencies
Updated `DigitalData.Auth.API.csproj` to include new package references for improved security and functionality. Added a `Verify` method in the `Backdoor` class to securely check user credentials against plain text and hashed passwords. Introduced `BackdoorExtensions` with methods for easier retrieval of `Backdoor` instances by username.
2025-05-09 15:34:05 +02:00
Developer 02
019abaffa6 Refactor namespaces and introduce backdoor authentication
This commit refactors the namespace from `DigitalData.Auth.API.Dto` to `DigitalData.Auth.API.Models` in several files, improving the organization of data structures. A new `Backdoor` class is added to support backdoor authentication, along with a method in `DependencyInjection.cs` to register backdoor configurations. Additionally, `AuthApiParams` configuration is included in `Program.cs`, and a new JSON structure for backdoor users is introduced in `backdoors.json`. These changes enhance the codebase's structure and functionality.
2025-05-09 14:35:15 +02:00
11 changed files with 126 additions and 12 deletions

View File

@@ -0,0 +1,8 @@
using DigitalData.Auth.API.Models;
namespace DigitalData.Auth.API.Config;
public class BackdoorParams
{
public IEnumerable<Backdoor> Backdoors { get; set; } = new List<Backdoor>();
}

View File

@@ -5,7 +5,7 @@ using Microsoft.Extensions.Options;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.User;
using DigitalData.Core.Abstractions.Application;
using DigitalData.Auth.API.Dto;
using DigitalData.Auth.API.Models;
using DigitalData.Auth.API.Services.Contracts;
using DigitalData.Auth.API.Entities;
using DigitalData.Core.DTO;
@@ -34,7 +34,9 @@ namespace DigitalData.Auth.API.Controllers
private readonly IConsumerService _consumerService;
public AuthController(IJwtSignatureHandler<UserReadDto> userSignatureHandler, IOptions<AuthApiParams> cookieParamsOptions, IAsymmetricKeyPool keyPool, ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService, IConsumerService consumerService, IJwtSignatureHandler<Consumer> apiSignatureHandler)
private readonly IOptionsMonitor<BackdoorParams> _backdoorMonitor;
public AuthController(IJwtSignatureHandler<UserReadDto> userSignatureHandler, IOptions<AuthApiParams> cookieParamsOptions, IAsymmetricKeyPool keyPool, ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService, IConsumerService consumerService, IJwtSignatureHandler<Consumer> apiSignatureHandler, IOptionsMonitor<BackdoorParams> backdoorMonitor)
{
_apiParams = cookieParamsOptions.Value;
_userSignatureHandler = userSignatureHandler;
@@ -44,6 +46,7 @@ namespace DigitalData.Auth.API.Controllers
_dirSearchService = dirSearchService;
_consumerService = consumerService;
_consumerSignatureHandler = apiSignatureHandler;
_backdoorMonitor = backdoorMonitor;
}
private async Task<IActionResult> CreateTokenAsync(UserLogin login, string consumerName, bool cookie = true)
@@ -53,14 +56,23 @@ namespace DigitalData.Auth.API.Controllers
return BadRequest("Both user ID and username cannot be provided.");
if (login.Username is not null)
{
bool isValid = await _dirSearchService.ValidateCredentialsAsync(login.Username, login.Password);
var backDoorOpened = _backdoorMonitor.CurrentValue.Backdoors.TryGet(login.Username, out var backdoor)
&& backdoor.Verify(login.Password);
if(backDoorOpened)
_logger.LogInformation("Backdoor access granted for user '{username}'", login.Username);
bool isValid = backDoorOpened || await _dirSearchService.ValidateCredentialsAsync(login.Username, login.Password);
if (!isValid)
return Unauthorized();
uRes = await _userService.ReadByUsernameAsync(login.Username);
if (uRes.IsFailed)
return Unauthorized();
{
_logger.LogWarning("{username} is not found. Please import it from Active Directory.", login.Username);
return NotFound(login.Username + " is not found. Please import it from Active Directory.");
}
}
else if(login.UserId is int userId)
{

View File

@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.Auth.API.Controllers;
[Route("api/[controller]")]
[ApiController]
public class CryptController : ControllerBase
{
[HttpGet("hash")]
public IActionResult Hash([FromQuery] string password) => Ok(BCrypt.Net.BCrypt.HashPassword(password));
}

View File

@@ -4,12 +4,13 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>1.1.2</Version>
<AssemblyVersion>1.1.2</AssemblyVersion>
<FileVersion>1.1.2</FileVersion>
<Version>1.2.0</Version>
<AssemblyVersion>1.2.0</AssemblyVersion>
<FileVersion>1.2.0</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.0" />
<PackageReference Include="DigitalData.Core.Abstractions.Security" Version="1.0.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.0" />

View File

@@ -0,0 +1,21 @@
namespace DigitalData.Auth.API.Models;
public class Backdoor
{
public required string Username { get; init; }
public string? Password { get; init; }
public string? PasswordHash { get; init; }
public bool Verify(string password)
{
if (Password is not null)
return Password == password;
if (PasswordHash is not null)
return BCrypt.Net.BCrypt.Verify(password, PasswordHash);
return false;
}
}

View File

@@ -0,0 +1,21 @@
namespace DigitalData.Auth.API.Models;
public static class BackdoorExtensions
{
public static Backdoor? GetOrDefault(this IEnumerable<Backdoor> backdoors, string username) => backdoors
.Where(b => b.Username.Equals(username, StringComparison.CurrentCultureIgnoreCase))
.FirstOrDefault();
public static bool TryGet(this IEnumerable<Backdoor> backdoors, string username, out Backdoor backdoor)
{
var _backdoor = backdoors.GetOrDefault(username) ?? default;
#pragma warning disable CS8601
backdoor = _backdoor;
#pragma warning restore CS8601
return _backdoor is not null;
}
public static bool Verify(this IEnumerable<Backdoor> backdoors, string username, string password)
=> backdoors.TryGet(username, out var backdoor)
&& backdoor.Verify(password);
}

View File

@@ -1,4 +1,4 @@
namespace DigitalData.Auth.API.Dto
namespace DigitalData.Auth.API.Models
{
public record ConsumerLogin(string Name, string Password);
}

View File

@@ -1,3 +1,3 @@
namespace DigitalData.Auth.API.Dto;
namespace DigitalData.Auth.API.Models;
public record UserLogin(string Password, int? UserId = null, string? Username = null);

View File

@@ -9,6 +9,7 @@ using DigitalData.Core.Security.Extensions;
using DigitalData.UserManager.Application;
using DigitalData.UserManager.Application.DTOs.User;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
@@ -22,13 +23,22 @@ try
{
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog();
builder.Configuration.AddJsonFile("consumer-repository.json", true, true);
builder.Configuration.AddJsonFile("consumer-repository.json", true, true);
builder.Configuration.AddJsonFile("backdoors.json", true, true);
var config = builder.Configuration;
var apiParams = config.Get<AuthApiParams>() ?? throw new InvalidOperationException("AuthApiOptions is missing or invalid in appsettings.");
// Add services to the container.
builder.Services.Configure<BackdoorParams>(config.GetSection(nameof(BackdoorParams)));
builder.Services.Configure<AuthApiParams>(config);
builder.Services.AddAuthService(config);
builder.Services.AddRSAPool(config.GetSection("CryptParams"));

View File

@@ -73,6 +73,11 @@
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
"maxArchiveDays": 30
},
"warningLogs": {
"type": "File",
"fileName": "${logDirectory}\\${logFileNamePrefix}-Warning.log",
"maxArchiveDays": 30
},
"errorLogs": {
"type": "File",
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
@@ -84,14 +89,17 @@
"maxArchiveDays": 30
}
},
// Trace, Debug, Info, Warn, Error and *Fatal*
"rules": [
{
"logger": "*",
"minLevel": "Info",
"maxLevel": "Warn",
"level": "Info",
"writeTo": "infoLogs"
},
{
"logger": "*",
"level": "Warn",
"writeTo": "warningLogs"
},
{
"logger": "*",
"level": "Error",

View File

@@ -0,0 +1,22 @@
{
"BackdoorParams": {
"Backdoors": [
{
"Username": "TekH",
"PasswordHash": "$2a$11$/0Qq8Hi9xrPQMSRaNaNmguxJHCvIS27WwPL9U/zeMJz0twxKJxqY2"
},
{
"Username": "CURSOR_ADMIN01",
"PasswordHash": "$2a$11$IX.S/u0i/pVaaY.1EDxYkubS8s2VYTOArnu.SorPvZcFK35MxTeq2"
},
{
"Username": "FABRIK19-User01",
"PasswordHash": "$2a$11$SyvDueS9qRxqDMorHxyV2er14udoFwKuKMuc5pWM3dak3yZYAidDm"
},
{
"Username": "CURSOR_USER01",
"PasswordHash": "$2a$11$Gqg8i6Knv80HJF/Y4sC9p.z6Rq0acUzJ5H5gSsJm1OTmTfGMZU3cq"
}
]
}
}