Skip to content

Commit

Permalink
Added AccessDataCacheService for cachiing, authservice for auth requests
Browse files Browse the repository at this point in the history
  • Loading branch information
ReallyWeirdCat committed Nov 5, 2024
1 parent fc23c59 commit a816322
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using AuthService.Services.Models;

namespace AuthService.Models.AccessDataCache.Requests;

public class RecacheUserRequest : UserAccessData;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace AuthService.Models.AccessDataCache.Responses;

public class RecacheUserResponse
{
public bool IsSuccess { get; set; }
}
2 changes: 1 addition & 1 deletion AuthService/Models/Auth/Requests/RefreshRequest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace AuthService.Models.Auth.Requests;
namespace AuthService.Models.Authentication.Requests;

public class RefreshRequest
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace AuthService.Models.Auth.Requests;
namespace AuthService.Models.Authentication.Requests;

public class ValidateAccessTokenRequest
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace AuthService.Models.Auth.Requests;
namespace AuthService.Models.Authentication.Requests;

public class ValidateRefreshTokenRequest
{
Expand Down
2 changes: 1 addition & 1 deletion AuthService/Models/Auth/Responses/RefreshResponse.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace AuthService.Models.Auth.Responses;
namespace AuthService.Models.Authentication.Responses;

public class RefreshResponse
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace AuthService.Models.Auth.Responses;
namespace AuthService.Models.Authentication.Responses;

public class ValidateAccessTokenResponse
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace AuthService.Models.Auth.Responses;
namespace AuthService.Models.Authentication.Responses;

public class ValidateRefreshTokenResponse
{
Expand Down
10 changes: 9 additions & 1 deletion AuthService/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Serilog;
using AuthService.Utils;
using AuthService.Services.Jwt;
using AuthService.Services.Authentication;
using AuthService.Services.AccessDataCache;

var builder = WebApplication.CreateBuilder(args);

Expand All @@ -9,6 +12,11 @@

var app = builder.Build();

app.UseHttpsRedirection();
builder.Services.AddSingleton<IConfiguration>(builder.Configuration);

builder.Services.AddScoped<IJwtService, JwtService>();
// TODO: implementation :D
//builder.Services.AddScoped<IAccessDataCacheService, AccessDataCacheService>();
builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();

app.Run();
28 changes: 28 additions & 0 deletions AuthService/Services/AccessDataCache/IAccessDataCacheService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using AuthService.Models.AccessDataCache.Requests;
using AuthService.Models.AccessDataCache.Responses;
using AuthService.Services.Models;

namespace AuthService.Services.AccessDataCache;

/// <summary>
/// IAccessDataCacheService служит для кэширования данных доступа пользователя.
/// </summary>
public interface IAccessDataCacheService
{

/// <summary>
/// Возвращает данные доступа пользователя по имени пользователя.
/// </summary>
Task<UserAccessData?> Get(string username);

/// <summary>
/// Позволяет запросить данные доступа пользователя у UserService, при этом автоматически кеширует их.
/// </summary>
Task<UserAccessData?> RequestAndCacheUser(string username);

/// <summary>
/// Открытый эндпоинт для микросервисов, который позволяет кешировать данные доступа пользователя (в том числе повторно, если они были обновлены).
/// </summary>
Task<RecacheUserResponse> RecacheUser(RecacheUserRequest user);

}
8 changes: 0 additions & 8 deletions AuthService/Services/Auth/IAuthService.cs

This file was deleted.

60 changes: 60 additions & 0 deletions AuthService/Services/Authentication/AuthService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using AuthService.Exceptions.Auth;
using AuthService.Models;
using AuthService.Models.Authentication.Requests;
using AuthService.Models.Authentication.Responses;
using AuthService.Services.AccessDataCache;
using AuthService.Services.Jwt;

namespace AuthService.Services.Authentication;

// TODO: we need more loggers in this code
public class AuthenticationService(IJwtService jwtService, IAccessDataCacheService accessDataCacheService, ILogger<AuthenticationService> logger) : IAuthenticationService
{
private readonly IJwtService _jwtService = jwtService;
private readonly IAccessDataCacheService _adcs = accessDataCacheService;
private readonly ILogger<AuthenticationService> _logger = logger;

public async Task<RefreshResponse> Refresh(RefreshRequest request)
{
string token = request.RefreshToken;
try
{
_logger.LogDebug("Validating refresh token via jwtService...");
var user = _jwtService.ValidateRefreshToken(token);

if (user == null)
{
_logger.LogDebug("Token validation was not successful");
throw new InvalidTokenException("Invalid refresh token");
}

_logger.LogDebug("Token was successfully validated, retrieving user data from ADCS...");

// FIXME: seperate error handling for event where user is not present in cache
var accessData = await _adcs.Get(user.Username) ?? throw new UserNotFoundException($"User not found: {user.Username}");

_logger.LogDebug("User data received, creating tokens via jwtService...");

return new RefreshResponse
{
AccessToken = _jwtService.GenerateAccessToken(accessData),
RefreshToken = _jwtService.GenerateRefreshToken(accessData)
};
}
catch (Exception)
{
_logger.LogDebug("Refresh token was rejected due to an error");
throw new InvalidTokenException("Invalid refresh token");
}
}

public Task<ValidatedUser> ValidateAccessToken(ValidateAccessTokenRequest request)
{
throw new NotImplementedException();
}

public Task<ValidatedUser> ValidateRefreshToken(ValidateRefreshTokenRequest request)
{
throw new NotImplementedException();
}
}
15 changes: 15 additions & 0 deletions AuthService/Services/Authentication/IAuthService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using AuthService.Models;
using AuthService.Models.Authentication.Requests;
using AuthService.Models.Authentication.Responses;

namespace AuthService.Services.Authentication;

/// <summary>
/// AuthService служит для аутентификации пользователя.
/// </summary>
public interface IAuthenticationService
{
public Task<ValidatedUser> ValidateAccessToken(ValidateAccessTokenRequest request);
public Task<ValidatedUser> ValidateRefreshToken(ValidateRefreshTokenRequest request);
public Task<RefreshResponse> Refresh(RefreshRequest request);
}
11 changes: 8 additions & 3 deletions AuthService/Services/Jwt/JwtService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
using AuthService.Exceptions.Auth;
using AuthService.Models;
using AuthService.Security;
using AuthService.Services.AccessDataCache;
using AuthService.Services.Models;
using Microsoft.IdentityModel.Tokens;

namespace AuthService.Services.Jwt;

public class JwtService(IConfiguration configuration, ILogger<JwtService> logger) : IJwtService
public class JwtService(IConfiguration configuration, IAccessDataCacheService accessDataCacheService, ILogger<JwtService> logger) : IJwtService
{
private readonly IAccessDataCacheService _adcs = accessDataCacheService;
private readonly IConfiguration _configuration = configuration;
private readonly ILogger<JwtService> _logger = logger;

Expand Down Expand Up @@ -69,10 +71,13 @@ private string GenerateToken(UserAccessData user, string tokenType, double expir
throw new InvalidTokenTypeException("Invalid token type");
}

// TODO: Get salt from token
string username = tokenHandler.ReadJwtToken(token).Claims.First(x => x.Type == ClaimTypes.Name).Value;
string salt = tokenHandler.ReadJwtToken(token).Claims.First(x => x.Type == JwtClaims.Salt).Value;
if (checkSalt)


if (checkSalt)
{
var accessData = _adcs.Get(username) ?? throw new UserNotFoundException($"User not found: {username}");
// TODO: If salt does not match the user, throw an exception
// throw new SessionTerminatedException("Invalid token");
}
Expand Down

0 comments on commit a816322

Please sign in to comment.