Merge pull request #10 from Qtoss-AI/issue-273

fix issue-273
This commit is contained in:
Haiping 2024-09-18 20:00:18 -05:00 committed by GitHub
commit 2bc15354bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 83 additions and 1 deletions

View file

@ -17,4 +17,5 @@ public interface IUserService
Task<bool> ModifyUserEmail(string email);
Task<bool> ModifyUserPhone(string phone);
Task<bool> UpdatePassword(string newPassword, string verificationCode);
Task<DateTime> GetUserTokenExpires();
}

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Users.Enums;
using BotSharp.Abstraction.Infrastructures;
using BotSharp.Abstraction.Users.Models;
using BotSharp.Abstraction.Users.Settings;
using BotSharp.OpenAPI.ViewModels.Users;
@ -229,10 +230,11 @@ public class UserService : IUserService
var audience = config["Jwt:Audience"];
var expireInMinutes = int.Parse(config["Jwt:ExpireInMinutes"] ?? "120");
var key = Encoding.ASCII.GetBytes(config["Jwt:Key"]);
var expires = DateTime.UtcNow.AddMinutes(expireInMinutes);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddMinutes(expireInMinutes),
Expires = expires,
Issuer = issuer,
Audience = audience,
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
@ -240,9 +242,27 @@ public class UserService : IUserService
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
SaveUserTokenExpiresCache(user.Id,expires).GetAwaiter().GetResult();
return tokenHandler.WriteToken(token);
}
private async Task SaveUserTokenExpiresCache(string userId, DateTime expires)
{
var _cacheService = _services.GetRequiredService<ICacheService>();
await _cacheService.SetAsync<DateTime>(GetUserTokenExpiresCacheKey(userId), expires, null);
}
private string GetUserTokenExpiresCacheKey(string userId)
{
return $"user_{userId}_token_expires";
}
public async Task<DateTime> GetUserTokenExpires()
{
var _cacheService = _services.GetRequiredService<ICacheService>();
return await _cacheService.GetAsync<DateTime>(GetUserTokenExpiresCacheKey(_user.Id));
}
[MemoryCache(10 * 60, perInstanceCache: true)]
public async Task<User> GetMyProfile()
{

View file

@ -11,6 +11,7 @@ using Microsoft.Net.Http.Headers;
using Microsoft.OpenApi.Models;
using Microsoft.IdentityModel.JsonWebTokens;
using BotSharp.OpenAPI.BackgroundServices;
using BotSharp.OpenAPI.Filters;
namespace BotSharp.OpenAPI;
@ -31,6 +32,11 @@ public static class BotSharpOpenApiExtensions
{
services.AddScoped<IUserIdentity, UserIdentity>();
services.AddHostedService<ConversationTimeoutService>();
services.AddMvc(options =>
{
options.Filters.Add<UserSingleLoginFilter>();
});
// Add bearer authentication
var schema = "MIXED_SCHEME";

View file

@ -0,0 +1,55 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Net.Http.Headers;
using System.IdentityModel.Tokens.Jwt;
namespace BotSharp.OpenAPI.Filters
{
public class UserSingleLoginFilter : IAuthorizationFilter
{
private readonly IUserService _userService;
public UserSingleLoginFilter(IUserService userService)
{
_userService = userService;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var bearerToken = GetBearerToken(context);
if (!string.IsNullOrWhiteSpace(bearerToken))
{
if (GetJwtTokenExpires(bearerToken).ToLongTimeString() != GetUserExpires().ToLongTimeString())
{
context.Result = new UnauthorizedResult();
}
}
}
private string GetBearerToken(AuthorizationFilterContext context)
{
if (context.HttpContext.Request.Headers.TryGetValue(HeaderNames.Authorization, out var bearerToken)
&& !string.IsNullOrWhiteSpace(bearerToken.ToString()))
{
var tokenType = bearerToken.ToString().Split(" ").First();
if (tokenType == JwtBearerDefaults.AuthenticationScheme)
{
return bearerToken.ToString().Split(" ").Last();
}
}
return null;
}
private DateTime GetJwtTokenExpires(string jwtToken)
{
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(jwtToken);
return token.ValidTo;
}
private DateTime GetUserExpires()
{
return _userService.GetUserTokenExpires().GetAwaiter().GetResult();
}
}
}