Compare commits

...

7 Commits

7 changed files with 97 additions and 2 deletions

@ -0,0 +1,9 @@
namespace Mirea.Api.Security.Common.Domain;
public class PreAuthToken
{
public required string Fingerprint { get; set; }
public required string UserAgent { get; set; }
public required string UserId { get; set; }
public required string Token { get; set; }
}

@ -0,0 +1,8 @@
namespace Mirea.Api.Security.Common.Dto.Requests;
public class TokenRequest
{
public required string Fingerprint { get; set; }
public required string UserAgent { get; set; }
public required string Ip { get; set; }
}

@ -0,0 +1,9 @@
using System;
namespace Mirea.Api.Security.Common.Dto.Responses;
public class PreAuthTokenResponse
{
public required string Token { get; set; }
public DateTime ExpiresIn { get; set; }
}

@ -0,0 +1,12 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Mirea.Api.Security.Common.Interfaces;
public interface ICacheService
{
Task SetAsync<T>(string key, T value, TimeSpan? absoluteExpirationRelativeToNow = null, CancellationToken cancellationToken = default);
Task<T?> GetAsync<T>(string key, CancellationToken cancellationToken = default);
Task RemoveAsync(string key, CancellationToken cancellationToken = default);
}

@ -1,11 +1,14 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Mirea.Api.Security.Common.Interfaces;
using Mirea.Api.Security.Services;
using System;
namespace Mirea.Api.Security;
public static class DependencyInjection
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services, IConfiguration configuration)
public static IServiceCollection AddSecurityServices(this IServiceCollection services, IConfiguration configuration)
{
var saltSize = int.Parse(configuration["SECURITY_SALT_SIZE"]!);
var hashSize = int.Parse(configuration["SECURITY_HASH_SIZE"]!);
@ -23,6 +26,18 @@ public static class DependencyInjection
Secret = configuration["SECURITY_HASH_TOKEN"]
});
var lifeTimeLogin = TimeSpan.FromMinutes(int.Parse(configuration["SECURITY_LIFE_TIME_1_FA"]!));
services.AddSingleton(provider =>
{
var cache = provider.GetRequiredService<ICacheService>();
return new PreAuthService(cache)
{
Lifetime = lifeTimeLogin
};
});
return services;
}
}

@ -3,7 +3,7 @@ using System;
using System.Buffers.Text;
using System.Text;
namespace Mirea.Api.Security;
namespace Mirea.Api.Security.Services;
public class PasswordHashService
{

@ -0,0 +1,42 @@
using Mirea.Api.Security.Common.Domain;
using Mirea.Api.Security.Common.Dto.Requests;
using Mirea.Api.Security.Common.Dto.Responses;
using Mirea.Api.Security.Common.Interfaces;
using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace Mirea.Api.Security.Services;
public class PreAuthService(ICacheService cache)
{
public TimeSpan Lifetime { private get; init; }
private static string GenerateFirstAuthToken() => Guid.NewGuid().ToString().Replace("-", "");
public async Task<PreAuthTokenResponse> CreateLoginTokenAsync(TokenRequest request, string userId, CancellationToken cancellation = default)
{
var firstAuthToken = GenerateFirstAuthToken();
var loginStructure = new PreAuthToken
{
Fingerprint = request.Fingerprint,
UserId = userId,
UserAgent = request.UserAgent,
Token = firstAuthToken
};
await cache.SetAsync(
request.Fingerprint,
JsonSerializer.SerializeToUtf8Bytes(loginStructure),
Lifetime,
cancellation);
return new PreAuthTokenResponse
{
Token = firstAuthToken,
ExpiresIn = DateTime.UtcNow.Add(Lifetime)
};
}
}