Add JWT authentication and role-based authorization

This commit is contained in:
steinhelge
2025-11-23 22:26:17 +01:00
parent 587847e7ed
commit 20af7d5b52
21 changed files with 1726 additions and 77 deletions
@@ -0,0 +1,96 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Hospitality.Backend.Configuration;
using Hospitality.Backend.DTOs;
using Hospitality.Domain.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
namespace Hospitality.Backend.Services;
public class AuthService : IAuthService
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly JwtSettings _jwtSettings;
public AuthService(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IOptions<JwtSettings> jwtSettings)
{
_userManager = userManager;
_signInManager = signInManager;
_jwtSettings = jwtSettings.Value;
}
public async Task<LoginResponse?> LoginAsync(LoginRequest request)
{
var user = await _userManager.FindByEmailAsync(request.Email);
if (user == null)
return null;
var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false);
if (!result.Succeeded)
return null;
var roles = await _userManager.GetRolesAsync(user);
var token = GenerateJwtToken(user, roles.ToArray());
return new LoginResponse(token, user.Email!, roles.ToArray());
}
public async Task<bool> RegisterAsync(RegisterRequest request)
{
var user = new ApplicationUser
{
UserName = request.Email,
Email = request.Email
};
var result = await _userManager.CreateAsync(user, request.Password);
if (!result.Succeeded)
return false;
await _userManager.AddToRoleAsync(user, request.Role);
return true;
}
public async Task<UserInfoResponse?> GetUserInfoAsync(string email)
{
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
return null;
var roles = await _userManager.GetRolesAsync(user);
return new UserInfoResponse(user.Email!, roles.ToArray());
}
private string GenerateJwtToken(ApplicationUser user, string[] roles)
{
var claims = new List<Claim>
{
new(ClaimTypes.NameIdentifier, user.Id),
new(ClaimTypes.Email, user.Email!),
new(JwtRegisteredClaimNames.Sub, user.Email!),
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _jwtSettings.Issuer,
audience: _jwtSettings.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(_jwtSettings.ExpirationMinutes),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
@@ -0,0 +1,10 @@
using Hospitality.Backend.DTOs;
namespace Hospitality.Backend.Services;
public interface IAuthService
{
Task<LoginResponse?> LoginAsync(LoginRequest request);
Task<bool> RegisterAsync(RegisterRequest request);
Task<UserInfoResponse?> GetUserInfoAsync(string email);
}