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> {
|
var claims = new List<Claim> {
|
||||||
new Claim(ClaimTypes.Name, name),
|
new Claim(ClaimTypes.Name, name),
|
||||||
new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
|
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()) };
|
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
|
||||||
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
||||||
|
|
||||||
|
@ -214,6 +215,7 @@ namespace Blog.Core.Controllers
|
||||||
var claims = new List<Claim> {
|
var claims = new List<Claim> {
|
||||||
new Claim(ClaimTypes.Name, user.LoginName),
|
new Claim(ClaimTypes.Name, user.LoginName),
|
||||||
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
|
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()) };
|
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
|
||||||
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Blog.Core.Model;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
@ -70,6 +71,8 @@ namespace Blog.Core.Common.HttpContextUser
|
||||||
return new List<string>() { };
|
return new List<string>() { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessageModel<string> MessageModel { get; set; }
|
||||||
|
|
||||||
public IEnumerable<Claim> GetClaimsIdentity()
|
public IEnumerable<Claim> GetClaimsIdentity()
|
||||||
{
|
{
|
||||||
var claims = _accessor.HttpContext.User.Claims.ToList();
|
var claims = _accessor.HttpContext.User.Claims.ToList();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Blog.Core.Model;
|
||||||
|
|
||||||
namespace Blog.Core.Common.HttpContextUser
|
namespace Blog.Core.Common.HttpContextUser
|
||||||
{
|
{
|
||||||
|
@ -13,5 +14,7 @@ namespace Blog.Core.Common.HttpContextUser
|
||||||
|
|
||||||
string GetToken();
|
string GetToken();
|
||||||
List<string> GetUserInfoFromToken(string ClaimType);
|
List<string> GetUserInfoFromToken(string ClaimType);
|
||||||
|
|
||||||
|
MessageModel<string> MessageModel { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,24 @@ using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Blog.Core.Common.HttpContextUser;
|
||||||
|
|
||||||
namespace Blog.Core.AuthHelper
|
namespace Blog.Core.AuthHelper
|
||||||
{
|
{
|
||||||
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
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()
|
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
|
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||||
{
|
{
|
||||||
Response.ContentType = "application/json";
|
Response.ContentType = "application/json";
|
||||||
|
@ -30,9 +35,16 @@ namespace Blog.Core.AuthHelper
|
||||||
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
||||||
{
|
{
|
||||||
Response.ContentType = "application/json";
|
Response.ContentType = "application/json";
|
||||||
Response.StatusCode = StatusCodes.Status403Forbidden;
|
if (_user.MessageModel != null)
|
||||||
await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE403)).MessageModel));
|
{
|
||||||
|
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 Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Blog.Core.Common.HttpContextUser;
|
||||||
|
using Blog.Core.Model;
|
||||||
|
|
||||||
namespace Blog.Core.AuthHelper
|
namespace Blog.Core.AuthHelper
|
||||||
{
|
{
|
||||||
|
@ -23,8 +26,11 @@ namespace Blog.Core.AuthHelper
|
||||||
/// 验证方案提供对象
|
/// 验证方案提供对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IAuthenticationSchemeProvider Schemes { get; set; }
|
public IAuthenticationSchemeProvider Schemes { get; set; }
|
||||||
|
|
||||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||||
private readonly IHttpContextAccessor _accessor;
|
private readonly IHttpContextAccessor _accessor;
|
||||||
|
private readonly ISysUserInfoServices _userServices;
|
||||||
|
private readonly IUser _user;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数注入
|
/// 构造函数注入
|
||||||
|
@ -32,9 +38,13 @@ namespace Blog.Core.AuthHelper
|
||||||
/// <param name="schemes"></param>
|
/// <param name="schemes"></param>
|
||||||
/// <param name="roleModulePermissionServices"></param>
|
/// <param name="roleModulePermissionServices"></param>
|
||||||
/// <param name="accessor"></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;
|
_accessor = accessor;
|
||||||
|
_userServices = userServices;
|
||||||
|
_user = user;
|
||||||
Schemes = schemes;
|
Schemes = schemes;
|
||||||
_roleModulePermissionServices = roleModulePermissionServices;
|
_roleModulePermissionServices = roleModulePermissionServices;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +84,7 @@ namespace Blog.Core.AuthHelper
|
||||||
Role = item.Role?.Name.ObjToString(),
|
Role = item.Role?.Name.ObjToString(),
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
requirement.Permissions = list;
|
requirement.Permissions = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +125,6 @@ namespace Blog.Core.AuthHelper
|
||||||
//result?.Principal不为空即登录成功
|
//result?.Principal不为空即登录成功
|
||||||
if (result?.Principal != null || isTestCurrent)
|
if (result?.Principal != null || isTestCurrent)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!isTestCurrent) httpContext.User = result.Principal;
|
if (!isTestCurrent) httpContext.User = result.Principal;
|
||||||
|
|
||||||
// 获取当前用户的角色信息
|
// 获取当前用户的角色信息
|
||||||
|
@ -160,6 +170,7 @@ namespace Blog.Core.AuthHelper
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断token是否过期,过期则重新登录
|
||||||
var isExp = false;
|
var isExp = false;
|
||||||
// ids4和jwt切换
|
// ids4和jwt切换
|
||||||
// ids4
|
// ids4
|
||||||
|
@ -172,18 +183,31 @@ namespace Blog.Core.AuthHelper
|
||||||
// jwt
|
// 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;
|
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);
|
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context.Fail();
|
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败
|
//判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败
|
||||||
if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)))
|
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);
|
//context.Succeed(requirement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
|
namespace Blog.Core.Model
|
||||||
namespace Blog.Core.Model
|
|
||||||
{
|
{
|
||||||
public class ApiResponse
|
public class ApiResponse
|
||||||
{
|
{
|
||||||
|
@ -12,28 +11,28 @@ namespace Blog.Core.Model
|
||||||
switch (apiCode)
|
switch (apiCode)
|
||||||
{
|
{
|
||||||
case StatusCode.CODE401:
|
case StatusCode.CODE401:
|
||||||
{
|
{
|
||||||
Status = 401;
|
Status = 401;
|
||||||
Value = "很抱歉,您无权访问该接口,请确保已经登录!";
|
Value = msg ?? "很抱歉,您无权访问该接口,请确保已经登录!";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StatusCode.CODE403:
|
case StatusCode.CODE403:
|
||||||
{
|
{
|
||||||
Status = 403;
|
Status = 403;
|
||||||
Value = "很抱歉,您的访问权限等级不够,联系管理员!";
|
Value = msg ?? "很抱歉,您的访问权限等级不够,联系管理员!";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StatusCode.CODE404:
|
case StatusCode.CODE404:
|
||||||
{
|
{
|
||||||
Status = 404;
|
Status = 404;
|
||||||
Value = "资源不存在!";
|
Value = "资源不存在!";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StatusCode.CODE500:
|
case StatusCode.CODE500:
|
||||||
{
|
{
|
||||||
Status = 500;
|
Status = 500;
|
||||||
Value = msg;
|
Value = msg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ namespace Blog.Core.Model
|
||||||
{
|
{
|
||||||
status = Status,
|
status = Status,
|
||||||
msg = Value,
|
msg = Value,
|
||||||
success = apiCode != StatusCode.CODE200
|
success = apiCode == StatusCode.CODE200
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,5 +53,4 @@ namespace Blog.Core.Model
|
||||||
CODE404,
|
CODE404,
|
||||||
CODE500
|
CODE500
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user