MireaBackend/Security/DependencyInjection.cs

92 lines
3.5 KiB
C#

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Mirea.Api.Security.Common.Domain;
using Mirea.Api.Security.Common.Interfaces;
using Mirea.Api.Security.Services;
using System;
using System.Collections.Generic;
using System.Text;
namespace Mirea.Api.Security;
public static class DependencyInjection
{
private static ReadOnlyMemory<byte> NormalizeKey(string key, int requiredLength)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
if (keyBytes.Length < requiredLength)
{
var normalizedKey = new byte[requiredLength];
Array.Copy(keyBytes, normalizedKey, keyBytes.Length);
return new ReadOnlyMemory<byte>(normalizedKey);
}
if (keyBytes.Length > requiredLength)
Array.Resize(ref keyBytes, requiredLength);
return new ReadOnlyMemory<byte>(keyBytes);
}
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"]!);
var iteration = int.Parse(configuration["SECURITY_HASH_ITERATION"]!);
var memory = int.Parse(configuration["SECURITY_HASH_MEMORY"]!);
var parallelism = int.Parse(configuration["SECURITY_HASH_PARALLELISM"]!);
services.AddSingleton(new PasswordHashService
{
SaltSize = saltSize,
HashSize = hashSize,
Iterations = iteration,
Memory = memory,
Parallelism = parallelism,
Secret = configuration["SECURITY_HASH_TOKEN"]
});
var lifeTimeRefreshToken = TimeSpan.FromMinutes(int.Parse(configuration["SECURITY_LIFE_TIME_RT"]!));
var lifeTimeFirstAuthToken = TimeSpan.FromMinutes(int.Parse(configuration["SECURITY_LIFE_TIME_1_FA"]!));
services.AddSingleton(provider =>
{
var cacheService = provider.GetRequiredService<ICacheService>();
var accessTokenService = provider.GetRequiredService<IAccessToken>();
var revokedTokenService = provider.GetRequiredService<IRevokedToken>();
var logger = provider.GetRequiredService<ILogger<AuthService>>();
var passwordService = provider.GetRequiredService<PasswordHashService>();
return new AuthService(cacheService, accessTokenService, revokedTokenService, logger, passwordService)
{
Lifetime = lifeTimeRefreshToken,
LifetimeFirstAuth = lifeTimeFirstAuthToken
};
});
var providers = new Dictionary<OAuthProvider, (string ClientId, string Secret)>();
foreach (var provider in Enum.GetValues<OAuthProvider>())
{
var providerName = Enum.GetName(provider)!.ToUpper();
var clientId = configuration[$"{providerName}_CLIENT_ID"];
var secret = configuration[$"{providerName}_CLIENT_SECRET"];
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(secret))
continue;
providers.Add(provider, (clientId, secret));
}
services.AddSingleton(provider => new OAuthService(
provider.GetRequiredService<ILogger<OAuthService>>(),
providers,
provider.GetRequiredService<ICacheService>())
{
SecretKey = NormalizeKey(configuration["SECURITY_ENCRYPTION_TOKEN"]!, 32)
});
return services;
}
}