Add JWT authentication and role-based authorization
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user