refactor: transfer logic
All logic related to token manipulation has been transferred to the AuthService. Also added TOTP 2FA and rethought the logic of logging into the application
This commit is contained in:
8
Security/Common/CookieNames.cs
Normal file
8
Security/Common/CookieNames.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Mirea.Api.Security.Common;
|
||||
|
||||
public class CookieNames
|
||||
{
|
||||
public const string AccessToken = "access_token";
|
||||
public const string RefreshToken = "refresh_token";
|
||||
public const string FingerprintToken = "fingerprint";
|
||||
}
|
@ -2,11 +2,25 @@
|
||||
|
||||
namespace Mirea.Api.Security.Common.Domain;
|
||||
|
||||
public class AuthToken
|
||||
internal class AuthToken
|
||||
{
|
||||
public required string RefreshToken { get; set; }
|
||||
public required string UserAgent { get; set; }
|
||||
public required string Ip { get; set; }
|
||||
public AuthToken(RequestContextInfo context)
|
||||
{
|
||||
UserAgent = context.UserAgent;
|
||||
Ip = context.Ip;
|
||||
Fingerprint = context.Fingerprint;
|
||||
RefreshToken = context.RefreshToken;
|
||||
}
|
||||
|
||||
public AuthToken()
|
||||
{
|
||||
}
|
||||
|
||||
public string UserAgent { get; set; } = null!;
|
||||
public string Ip { get; set; } = null!;
|
||||
public string Fingerprint { get; set; } = null!;
|
||||
public string RefreshToken { get; set; } = null!;
|
||||
|
||||
public required string UserId { get; set; }
|
||||
public required string AccessToken { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
29
Security/Common/Domain/CookieOptionsParameters.cs
Normal file
29
Security/Common/Domain/CookieOptionsParameters.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
|
||||
namespace Mirea.Api.Security.Common.Domain;
|
||||
|
||||
public class CookieOptionsParameters
|
||||
{
|
||||
public required string Domain { get; set; }
|
||||
public required string Path { get; set; }
|
||||
|
||||
internal void SetCookie(HttpContext context, string name, string value, DateTimeOffset? expires = null)
|
||||
{
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
Expires = expires,
|
||||
Path = Path,
|
||||
Domain = Domain,
|
||||
HttpOnly = true,
|
||||
#if !DEBUG
|
||||
Secure = true
|
||||
#endif
|
||||
};
|
||||
|
||||
context.Response.Cookies.Append(name, value, cookieOptions);
|
||||
}
|
||||
|
||||
internal void DropCookie(HttpContext context, string name) =>
|
||||
SetCookie(context, name, "", DateTimeOffset.MinValue);
|
||||
}
|
22
Security/Common/Domain/FirstAuthToken.cs
Normal file
22
Security/Common/Domain/FirstAuthToken.cs
Normal file
@ -0,0 +1,22 @@
|
||||
namespace Mirea.Api.Security.Common.Domain;
|
||||
|
||||
internal class FirstAuthToken
|
||||
{
|
||||
public FirstAuthToken(RequestContextInfo context)
|
||||
{
|
||||
UserAgent = context.UserAgent;
|
||||
Ip = context.Ip;
|
||||
Fingerprint = context.Fingerprint;
|
||||
}
|
||||
|
||||
public FirstAuthToken()
|
||||
{
|
||||
}
|
||||
|
||||
public string UserAgent { get; set; } = null!;
|
||||
public string Ip { get; set; } = null!;
|
||||
public string Fingerprint { get; set; } = null!;
|
||||
public required string UserId { get; set; }
|
||||
public required SecondFactor SecondFactor { get; set; }
|
||||
public string? Secret { get; set; }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
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 Ip { get; set; }
|
||||
public required string Token { get; set; }
|
||||
}
|
38
Security/Common/Domain/RequestContextInfo.cs
Normal file
38
Security/Common/Domain/RequestContextInfo.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Mirea.Api.Security.Services;
|
||||
using System;
|
||||
using System.Security;
|
||||
|
||||
namespace Mirea.Api.Security.Common.Domain;
|
||||
|
||||
internal class RequestContextInfo
|
||||
{
|
||||
public RequestContextInfo(HttpContext context, CookieOptionsParameters cookieOptions)
|
||||
{
|
||||
var ipEntity = context.Connection.RemoteIpAddress;
|
||||
|
||||
if (string.IsNullOrEmpty(ipEntity?.ToString()))
|
||||
throw new SecurityException("Ip is required for authorization.");
|
||||
|
||||
var ip = ipEntity.MapToIPv4().ToString();
|
||||
|
||||
var userAgent = context.Request.Headers.UserAgent.ToString();
|
||||
var fingerprint = context.Request.Cookies[CookieNames.FingerprintToken];
|
||||
|
||||
if (string.IsNullOrEmpty(fingerprint))
|
||||
{
|
||||
fingerprint = Guid.NewGuid().ToString().Replace("-", "") + GeneratorKey.GenerateString(32);
|
||||
cookieOptions.SetCookie(context, CookieNames.FingerprintToken, fingerprint);
|
||||
}
|
||||
|
||||
UserAgent = userAgent;
|
||||
Fingerprint = fingerprint;
|
||||
Ip = ip;
|
||||
RefreshToken = context.Request.Cookies["refresh_token"] ?? string.Empty;
|
||||
}
|
||||
|
||||
public string UserAgent { get; private set; }
|
||||
public string Ip { get; private set; }
|
||||
public string Fingerprint { get; private set; }
|
||||
public string RefreshToken { get; private set; }
|
||||
}
|
18
Security/Common/Domain/User.cs
Normal file
18
Security/Common/Domain/User.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace Mirea.Api.Security.Common.Domain;
|
||||
|
||||
public enum SecondFactor
|
||||
{
|
||||
None,
|
||||
Totp
|
||||
}
|
||||
|
||||
public class User
|
||||
{
|
||||
public required int Id { get; set; }
|
||||
public required string Username { get; set; }
|
||||
public required string Email { get; set; }
|
||||
public required string PasswordHash { get; set; }
|
||||
public required string Salt { get; set; }
|
||||
public required SecondFactor SecondFactor { get; set; }
|
||||
public string? SecondFactorToken { get; set; }
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
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; }
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Mirea.Api.Security.Common.Dto.Responses;
|
||||
|
||||
public class AuthTokenResponse
|
||||
{
|
||||
public required string AccessToken { get; set; }
|
||||
public DateTime AccessExpiresIn { get; set; }
|
||||
public required string RefreshToken { get; set; }
|
||||
public DateTime RefreshExpiresIn { get; set; }
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Mirea.Api.Security.Common.Dto.Responses;
|
||||
|
||||
public class PreAuthTokenResponse
|
||||
{
|
||||
public required string Token { get; set; }
|
||||
public DateTime ExpiresIn { get; set; }
|
||||
}
|
Reference in New Issue
Block a user