mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
✨ Token 增加签名时间 🐛解决一个小bug MessageModel.success 赋值错误
1.解决用户修改关键信息后(如修改密码、修改名称等等) token不会失效 2.可解决用户修改部门、角色、权限后 token失效 只需要刷新User的修改时间
This commit is contained in:
parent
08464db50d
commit
03de3abe08
|
@ -160,6 +160,7 @@ namespace Blog.Core.Controllers
|
|||
var claims = new List<Claim> {
|
||||
new Claim(ClaimTypes.Name, name),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
|
||||
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
|
||||
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
||||
|
||||
|
@ -214,6 +215,7 @@ namespace Blog.Core.Controllers
|
|||
var claims = new List<Claim> {
|
||||
new Claim(ClaimTypes.Name, user.LoginName),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
|
||||
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
|
||||
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Blog.Core.Model;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
@ -70,6 +71,8 @@ namespace Blog.Core.Common.HttpContextUser
|
|||
return new List<string>() { };
|
||||
}
|
||||
|
||||
public MessageModel<string> MessageModel { get; set; }
|
||||
|
||||
public IEnumerable<Claim> GetClaimsIdentity()
|
||||
{
|
||||
var claims = _accessor.HttpContext.User.Claims.ToList();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Blog.Core.Model;
|
||||
|
||||
namespace Blog.Core.Common.HttpContextUser
|
||||
{
|
||||
|
@ -13,5 +14,7 @@ namespace Blog.Core.Common.HttpContextUser
|
|||
|
||||
string GetToken();
|
||||
List<string> GetUserInfoFromToken(string ClaimType);
|
||||
|
||||
MessageModel<string> MessageModel { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,24 @@ using Newtonsoft.Json;
|
|||
using System;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Common.HttpContextUser;
|
||||
|
||||
namespace Blog.Core.AuthHelper
|
||||
{
|
||||
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
private readonly IUser _user;
|
||||
|
||||
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUser user) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
Response.ContentType = "application/json";
|
||||
|
@ -30,9 +35,16 @@ namespace Blog.Core.AuthHelper
|
|||
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
||||
{
|
||||
Response.ContentType = "application/json";
|
||||
Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE403)).MessageModel));
|
||||
if (_user.MessageModel != null)
|
||||
{
|
||||
Response.StatusCode = _user.MessageModel.status;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject(_user.MessageModel));
|
||||
}
|
||||
else
|
||||
{
|
||||
Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE403)).MessageModel));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,10 +7,13 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Common.HttpContextUser;
|
||||
using Blog.Core.Model;
|
||||
|
||||
namespace Blog.Core.AuthHelper
|
||||
{
|
||||
|
@ -23,8 +26,11 @@ namespace Blog.Core.AuthHelper
|
|||
/// 验证方案提供对象
|
||||
/// </summary>
|
||||
public IAuthenticationSchemeProvider Schemes { get; set; }
|
||||
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
private readonly ISysUserInfoServices _userServices;
|
||||
private readonly IUser _user;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数注入
|
||||
|
@ -32,9 +38,13 @@ namespace Blog.Core.AuthHelper
|
|||
/// <param name="schemes"></param>
|
||||
/// <param name="roleModulePermissionServices"></param>
|
||||
/// <param name="accessor"></param>
|
||||
public PermissionHandler(IAuthenticationSchemeProvider schemes, IRoleModulePermissionServices roleModulePermissionServices, IHttpContextAccessor accessor)
|
||||
/// <param name="userServices"></param>
|
||||
/// <param name="user"></param>
|
||||
public PermissionHandler(IAuthenticationSchemeProvider schemes, IRoleModulePermissionServices roleModulePermissionServices, IHttpContextAccessor accessor, ISysUserInfoServices userServices, IUser user)
|
||||
{
|
||||
_accessor = accessor;
|
||||
_userServices = userServices;
|
||||
_user = user;
|
||||
Schemes = schemes;
|
||||
_roleModulePermissionServices = roleModulePermissionServices;
|
||||
}
|
||||
|
@ -74,6 +84,7 @@ namespace Blog.Core.AuthHelper
|
|||
Role = item.Role?.Name.ObjToString(),
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
requirement.Permissions = list;
|
||||
}
|
||||
|
||||
|
@ -114,7 +125,6 @@ namespace Blog.Core.AuthHelper
|
|||
//result?.Principal不为空即登录成功
|
||||
if (result?.Principal != null || isTestCurrent)
|
||||
{
|
||||
|
||||
if (!isTestCurrent) httpContext.User = result.Principal;
|
||||
|
||||
// 获取当前用户的角色信息
|
||||
|
@ -160,6 +170,7 @@ namespace Blog.Core.AuthHelper
|
|||
return;
|
||||
}
|
||||
|
||||
// 判断token是否过期,过期则重新登录
|
||||
var isExp = false;
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
|
@ -172,18 +183,31 @@ namespace Blog.Core.AuthHelper
|
|||
// jwt
|
||||
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
|
||||
}
|
||||
if (isExp)
|
||||
|
||||
if (!isExp)
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Fail();
|
||||
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||
return;
|
||||
}
|
||||
|
||||
//校验签发时间
|
||||
var value = httpContext.User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null)
|
||||
{
|
||||
var user = await _userServices.QueryById(_user.ID, true);
|
||||
if (user.UpdateTime > value.ObjToDate())
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE403, "很抱歉,授权已失效,请重新授权").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context.Succeed(requirement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败
|
||||
if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)))
|
||||
{
|
||||
|
@ -195,4 +219,4 @@ namespace Blog.Core.AuthHelper
|
|||
//context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
namespace Blog.Core.Model
|
||||
namespace Blog.Core.Model
|
||||
{
|
||||
public class ApiResponse
|
||||
{
|
||||
|
@ -12,28 +11,28 @@ namespace Blog.Core.Model
|
|||
switch (apiCode)
|
||||
{
|
||||
case StatusCode.CODE401:
|
||||
{
|
||||
Status = 401;
|
||||
Value = "很抱歉,您无权访问该接口,请确保已经登录!";
|
||||
}
|
||||
{
|
||||
Status = 401;
|
||||
Value = msg ?? "很抱歉,您无权访问该接口,请确保已经登录!";
|
||||
}
|
||||
break;
|
||||
case StatusCode.CODE403:
|
||||
{
|
||||
Status = 403;
|
||||
Value = "很抱歉,您的访问权限等级不够,联系管理员!";
|
||||
}
|
||||
{
|
||||
Status = 403;
|
||||
Value = msg ?? "很抱歉,您的访问权限等级不够,联系管理员!";
|
||||
}
|
||||
break;
|
||||
case StatusCode.CODE404:
|
||||
{
|
||||
Status = 404;
|
||||
Value = "资源不存在!";
|
||||
}
|
||||
{
|
||||
Status = 404;
|
||||
Value = "资源不存在!";
|
||||
}
|
||||
break;
|
||||
case StatusCode.CODE500:
|
||||
{
|
||||
Status = 500;
|
||||
Value = msg;
|
||||
}
|
||||
{
|
||||
Status = 500;
|
||||
Value = msg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -41,7 +40,7 @@ namespace Blog.Core.Model
|
|||
{
|
||||
status = Status,
|
||||
msg = Value,
|
||||
success = apiCode != StatusCode.CODE200
|
||||
success = apiCode == StatusCode.CODE200
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -54,5 +53,4 @@ namespace Blog.Core.Model
|
|||
CODE404,
|
||||
CODE500
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user