commit
2bc15354bf
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue