mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
✨ 优化Swagger
1.swagger登录可以用用户账号登录,如果登录成功 token存在session中 之前默认admin感觉没什么用 当然也可以扩展User 加个字段是否开发者帐户等类似的 2.优化权限校验 优先读取Header->没有读取Session 中token解析用户
This commit is contained in:
parent
a979d36461
commit
0cea9672b5
|
@ -177,7 +177,7 @@
|
|||
登录管理【无权限】
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Controllers.LoginController.#ctor(Blog.Core.IServices.ISysUserInfoServices,Blog.Core.IServices.IUserRoleServices,Blog.Core.IServices.IRoleServices,Blog.Core.AuthHelper.PermissionRequirement,Blog.Core.IServices.IRoleModulePermissionServices)">
|
||||
<member name="M:Blog.Core.Controllers.LoginController.#ctor(Blog.Core.IServices.ISysUserInfoServices,Blog.Core.IServices.IUserRoleServices,Blog.Core.IServices.IRoleServices,Blog.Core.AuthHelper.PermissionRequirement,Blog.Core.IServices.IRoleModulePermissionServices,Microsoft.Extensions.Logging.ILogger{Blog.Core.Controllers.LoginController})">
|
||||
<summary>
|
||||
构造函数注入
|
||||
</summary>
|
||||
|
|
|
@ -9,307 +9,330 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using Blog.Core.Common.Swagger;
|
||||
using Serilog;
|
||||
|
||||
|
||||
namespace Blog.Core.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录管理【无权限】
|
||||
/// </summary>
|
||||
[Produces("application/json")]
|
||||
[Route("api/Login")]
|
||||
[AllowAnonymous]
|
||||
public class LoginController : BaseApiController
|
||||
{
|
||||
readonly ISysUserInfoServices _sysUserInfoServices;
|
||||
readonly IUserRoleServices _userRoleServices;
|
||||
readonly IRoleServices _roleServices;
|
||||
readonly PermissionRequirement _requirement;
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
/// <summary>
|
||||
/// 登录管理【无权限】
|
||||
/// </summary>
|
||||
[Produces("application/json")]
|
||||
[Route("api/Login")]
|
||||
[AllowAnonymous]
|
||||
public class LoginController : BaseApiController
|
||||
{
|
||||
readonly ISysUserInfoServices _sysUserInfoServices;
|
||||
readonly IUserRoleServices _userRoleServices;
|
||||
readonly IRoleServices _roleServices;
|
||||
readonly PermissionRequirement _requirement;
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly ILogger<LoginController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数注入
|
||||
/// </summary>
|
||||
/// <param name="sysUserInfoServices"></param>
|
||||
/// <param name="userRoleServices"></param>
|
||||
/// <param name="roleServices"></param>
|
||||
/// <param name="requirement"></param>
|
||||
/// <param name="roleModulePermissionServices"></param>
|
||||
public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices,
|
||||
IRoleServices roleServices, PermissionRequirement requirement,
|
||||
IRoleModulePermissionServices roleModulePermissionServices, ILogger<LoginController> logger)
|
||||
{
|
||||
this._sysUserInfoServices = sysUserInfoServices;
|
||||
this._userRoleServices = userRoleServices;
|
||||
this._roleServices = roleServices;
|
||||
_requirement = requirement;
|
||||
_roleModulePermissionServices = roleModulePermissionServices;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数注入
|
||||
/// </summary>
|
||||
/// <param name="sysUserInfoServices"></param>
|
||||
/// <param name="userRoleServices"></param>
|
||||
/// <param name="roleServices"></param>
|
||||
/// <param name="requirement"></param>
|
||||
/// <param name="roleModulePermissionServices"></param>
|
||||
public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices, IRoleServices roleServices, PermissionRequirement requirement, IRoleModulePermissionServices roleModulePermissionServices)
|
||||
{
|
||||
this._sysUserInfoServices = sysUserInfoServices;
|
||||
this._userRoleServices = userRoleServices;
|
||||
this._roleServices = roleServices;
|
||||
_requirement = requirement;
|
||||
_roleModulePermissionServices = roleModulePermissionServices;
|
||||
}
|
||||
#region 获取token的第1种方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取JWT的方法1
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("Token")]
|
||||
public async Task<MessageModel<string>> GetJwtStr(string name, string pass)
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
bool suc = false;
|
||||
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
||||
|
||||
var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
|
||||
if (user != null)
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt {Uid = 1, Role = user};
|
||||
|
||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
suc = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
jwtStr = "login fail!!!";
|
||||
}
|
||||
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = suc,
|
||||
msg = suc ? "获取成功" : "获取失败",
|
||||
response = jwtStr
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#region 获取token的第1种方法
|
||||
/// <summary>
|
||||
/// 获取JWT的方法2:给Nuxt提供
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("GetTokenNuxt")]
|
||||
public MessageModel<string> GetJwtStrForNuxt(string name, string pass)
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
bool suc = false;
|
||||
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
||||
//这里直接写死了
|
||||
if (name == "admins" && pass == "admins")
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt
|
||||
{
|
||||
Uid = 1,
|
||||
Role = "Admin"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获取JWT的方法1
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("Token")]
|
||||
public async Task<MessageModel<string>> GetJwtStr(string name, string pass)
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
bool suc = false;
|
||||
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
suc = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
jwtStr = "login fail!!!";
|
||||
}
|
||||
|
||||
var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
|
||||
if (user != null)
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = user };
|
||||
var result = new
|
||||
{
|
||||
data = new {success = suc, token = jwtStr}
|
||||
};
|
||||
|
||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
suc = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
jwtStr = "login fail!!!";
|
||||
}
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = suc,
|
||||
msg = suc ? "获取成功" : "获取失败",
|
||||
response = jwtStr
|
||||
};
|
||||
}
|
||||
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = suc,
|
||||
msg = suc ? "获取成功" : "获取失败",
|
||||
response = jwtStr
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取JWT的方法2:给Nuxt提供
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("GetTokenNuxt")]
|
||||
public MessageModel<string> GetJwtStrForNuxt(string name, string pass)
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
bool suc = false;
|
||||
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
||||
//这里直接写死了
|
||||
if (name == "admins" && pass == "admins")
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt
|
||||
{
|
||||
Uid = 1,
|
||||
Role = "Admin"
|
||||
};
|
||||
/// <summary>
|
||||
/// 获取JWT的方法3:整个系统主要方法
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("JWTToken3.0")]
|
||||
public async Task<MessageModel<TokenInfoViewModel>> GetJwtToken3(string name = "", string pass = "")
|
||||
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
|
||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
suc = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
jwtStr = "login fail!!!";
|
||||
}
|
||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
|
||||
return Failed<TokenInfoViewModel>("用户名或密码不能为空");
|
||||
|
||||
var result = new
|
||||
{
|
||||
data = new { success = suc, token = jwtStr }
|
||||
};
|
||||
pass = MD5Helper.MD5Encrypt32(pass);
|
||||
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = suc,
|
||||
msg = suc ? "获取成功" : "获取失败",
|
||||
response = jwtStr
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
var user = await _sysUserInfoServices.Query(d =>
|
||||
d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false);
|
||||
if (user.Count > 0)
|
||||
{
|
||||
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
|
||||
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, name),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
|
||||
new Claim("TenantId", user.FirstOrDefault().TenantId.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)));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取JWT的方法3:整个系统主要方法
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("JWTToken3.0")]
|
||||
public async Task<MessageModel<TokenInfoViewModel>> GetJwtToken3(string name = "", string pass = "")
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
// ids4和jwt切换
|
||||
// jwt
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
var data = await _roleModulePermissionServices.RoleModuleMaps();
|
||||
var list = (from item in data
|
||||
where item.IsDeleted == false
|
||||
orderby item.Id
|
||||
select new PermissionItem
|
||||
{
|
||||
Url = item.Module?.LinkUrl,
|
||||
Role = item.Role?.Name.ObjToString(),
|
||||
}).ToList();
|
||||
|
||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
|
||||
return Failed<TokenInfoViewModel>("用户名或密码不能为空");
|
||||
_requirement.Permissions = list;
|
||||
}
|
||||
|
||||
pass = MD5Helper.MD5Encrypt32(pass);
|
||||
var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||
return Success(token, "获取成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed<TokenInfoViewModel>("认证失败");
|
||||
}
|
||||
}
|
||||
|
||||
var user = await _sysUserInfoServices.Query(d => d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false);
|
||||
if (user.Count > 0)
|
||||
{
|
||||
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
|
||||
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, name),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
|
||||
new Claim("TenantId", user.FirstOrDefault().TenantId.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)));
|
||||
/// <summary>
|
||||
/// 请求刷新Token(以旧换新)
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("RefreshToken")]
|
||||
public async Task<MessageModel<TokenInfoViewModel>> RefreshToken(string token = "")
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return Failed<TokenInfoViewModel>("token无效,请重新登录!");
|
||||
var tokenModel = JwtHelper.SerializeJwt(token);
|
||||
if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
|
||||
{
|
||||
var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
|
||||
var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null && user.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
return Failed<TokenInfoViewModel>("很抱歉,授权已失效,请重新授权!");
|
||||
}
|
||||
|
||||
if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate()))
|
||||
{
|
||||
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.LoginName, user.LoginPWD);
|
||||
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
||||
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)));
|
||||
|
||||
//用户标识
|
||||
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
|
||||
identity.AddClaims(claims);
|
||||
|
||||
var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||
return Success(refreshToken, "获取成功");
|
||||
}
|
||||
}
|
||||
|
||||
return Failed<TokenInfoViewModel>("认证失败!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取JWT的方法4:给 JSONP 测试
|
||||
/// </summary>
|
||||
/// <param name="callBack"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="sub"></param>
|
||||
/// <param name="expiresSliding"></param>
|
||||
/// <param name="expiresAbsoulute"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("jsonp")]
|
||||
public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30,
|
||||
int expiresAbsoulute = 30)
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt
|
||||
{
|
||||
Uid = id,
|
||||
Role = sub
|
||||
};
|
||||
|
||||
string jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
|
||||
string response = string.Format("\"value\":\"{0}\"", jwtStr);
|
||||
string call = callBack + "({" + response + "})";
|
||||
Response.WriteAsync(call);
|
||||
}
|
||||
|
||||
|
||||
// ids4和jwt切换
|
||||
// jwt
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
var data = await _roleModulePermissionServices.RoleModuleMaps();
|
||||
var list = (from item in data
|
||||
where item.IsDeleted == false
|
||||
orderby item.Id
|
||||
select new PermissionItem
|
||||
{
|
||||
Url = item.Module?.LinkUrl,
|
||||
Role = item.Role?.Name.ObjToString(),
|
||||
}).ToList();
|
||||
/// <summary>
|
||||
/// 测试 MD5 加密字符串
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("Md5Password")]
|
||||
public string Md5Password(string password = "")
|
||||
{
|
||||
return MD5Helper.MD5Encrypt32(password);
|
||||
}
|
||||
|
||||
_requirement.Permissions = list;
|
||||
}
|
||||
/// <summary>
|
||||
/// swagger登录
|
||||
/// </summary>
|
||||
/// <param name="loginRequest"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("/api/Login/swgLogin")]
|
||||
public async Task<dynamic> SwgLogin([FromBody] SwaggerLoginRequest loginRequest)
|
||||
{
|
||||
if (loginRequest is null)
|
||||
{
|
||||
return new {result = false};
|
||||
}
|
||||
|
||||
var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||
return Success(token, "获取成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed<TokenInfoViewModel>("认证失败");
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
var result = await GetJwtToken3(loginRequest.name, loginRequest.pwd);
|
||||
if (result.success)
|
||||
{
|
||||
HttpContext.SuccessSwagger();
|
||||
HttpContext.SuccessSwaggerJwt(result.response.token);
|
||||
return new {result = true};
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Swagger登录异常");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求刷新Token(以旧换新)
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("RefreshToken")]
|
||||
public async Task<MessageModel<TokenInfoViewModel>> RefreshToken(string token = "")
|
||||
{
|
||||
string jwtStr = string.Empty;
|
||||
return new {result = false};
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return Failed<TokenInfoViewModel>("token无效,请重新登录!");
|
||||
var tokenModel = JwtHelper.SerializeJwt(token);
|
||||
if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
|
||||
{
|
||||
var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
|
||||
var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null && user.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
return Failed<TokenInfoViewModel>("很抱歉,授权已失效,请重新授权!");
|
||||
}
|
||||
/// <summary>
|
||||
/// weixin登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("wxLogin")]
|
||||
public dynamic WxLogin(string g = "", string token = "")
|
||||
{
|
||||
return new {g, token};
|
||||
}
|
||||
}
|
||||
|
||||
if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate()))
|
||||
{
|
||||
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.LoginName, user.LoginPWD);
|
||||
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
||||
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)));
|
||||
|
||||
//用户标识
|
||||
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
|
||||
identity.AddClaims(claims);
|
||||
|
||||
var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||
return Success(refreshToken, "获取成功");
|
||||
}
|
||||
}
|
||||
|
||||
return Failed<TokenInfoViewModel>("认证失败!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取JWT的方法4:给 JSONP 测试
|
||||
/// </summary>
|
||||
/// <param name="callBack"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="sub"></param>
|
||||
/// <param name="expiresSliding"></param>
|
||||
/// <param name="expiresAbsoulute"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("jsonp")]
|
||||
public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30, int expiresAbsoulute = 30)
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt
|
||||
{
|
||||
Uid = id,
|
||||
Role = sub
|
||||
};
|
||||
|
||||
string jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
|
||||
string response = string.Format("\"value\":\"{0}\"", jwtStr);
|
||||
string call = callBack + "({" + response + "})";
|
||||
Response.WriteAsync(call);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 测试 MD5 加密字符串
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("Md5Password")]
|
||||
public string Md5Password(string password = "")
|
||||
{
|
||||
return MD5Helper.MD5Encrypt32(password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// swagger登录
|
||||
/// </summary>
|
||||
/// <param name="loginRequest"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("/api/Login/swgLogin")]
|
||||
public dynamic SwgLogin([FromBody] SwaggerLoginRequest loginRequest)
|
||||
{
|
||||
// 这里可以查询数据库等各种校验
|
||||
if (loginRequest?.name == "admin" && loginRequest?.pwd == "admin")
|
||||
{
|
||||
HttpContext.Session.SetString("swagger-code", "success");
|
||||
return new { result = true };
|
||||
}
|
||||
|
||||
return new { result = false };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// weixin登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("wxLogin")]
|
||||
public dynamic WxLogin(string g = "", string token = "")
|
||||
{
|
||||
return new { g, token };
|
||||
}
|
||||
}
|
||||
|
||||
public class SwaggerLoginRequest
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string pwd { get; set; }
|
||||
}
|
||||
public class SwaggerLoginRequest
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string pwd { get; set; }
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@
|
|||
},
|
||||
"LogToDb": true,
|
||||
"LogAOP": {
|
||||
"Enabled": true,
|
||||
"Enabled": false,
|
||||
"LogToFile": {
|
||||
"Enabled": true
|
||||
},
|
||||
|
|
|
@ -1,128 +1,141 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta charset="utf-8"/>
|
||||
<title>登录 - 接口文档</title>
|
||||
<script src="js/jquery-3.3.1.min.js"></script>
|
||||
<link type="text/css" href="css/style.css" rel="stylesheet" />
|
||||
<link type="text/css" href="css/style.css" rel="stylesheet"/>
|
||||
<script src="js/anime.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<div class="container">
|
||||
<div class="left">
|
||||
<div></div>
|
||||
<div class="page">
|
||||
<div class="container">
|
||||
<div class="left">
|
||||
<div></div>
|
||||
|
||||
<div class="login"><img src="/logo.jpg.jpg" height="30" alt="Alternate Text"/> Blog.Core 接口文档</div>
|
||||
<div class="eula">欢迎使用!</div>
|
||||
<div class="eula">用户名:admin,密码:admin</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<svg viewBox="0 0 320 300">
|
||||
<defs>
|
||||
<linearGradient inkscape:collect="always"
|
||||
id="linearGradient"
|
||||
x1="13"
|
||||
y1="193.49992"
|
||||
x2="307"
|
||||
y2="193.49992"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop style="stop-color:#ff00ff;"
|
||||
offset="0"
|
||||
id="stop876" />
|
||||
<stop style="stop-color:#ff0000;"
|
||||
offset="1"
|
||||
id="stop878" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="m 40,120.00016 239.99984,-3.2e-4 c 0,0 24.99263,0.79932 25.00016,35.00016 0.008,34.20084 -25.00016,35 -25.00016,35 h -239.99984 c 0,-0.0205 -25,4.01348 -25,38.5 0,34.48652 25,38.5 25,38.5 h 215 c 0,0 20,-0.99604 20,-25 0,-24.00396 -20,-25 -20,-25 h -190 c 0,0 -20,1.71033 -20,25 0,24.00396 20,25 20,25 h 168.57143" />
|
||||
</svg>
|
||||
<div class="form">
|
||||
<label for="email">用户名</label>
|
||||
<input type="email" id="email">
|
||||
<label for="password">密码</label>
|
||||
<input type="password" id="password">
|
||||
<input type="submit" id="submit" onclick="submit()" value="登 录">
|
||||
</div>
|
||||
<div class="login"><img src="/logo.jpg.jpg" height="30" alt="Alternate Text"/> Blog.Core 接口文档</div>
|
||||
<div class="eula">欢迎使用!</div>
|
||||
<div class="eula">使用用户账号登录</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<svg viewBox="0 0 320 300">
|
||||
<defs>
|
||||
<linearGradient inkscape:collect="always"
|
||||
id="linearGradient"
|
||||
x1="13"
|
||||
y1="193.49992"
|
||||
x2="307"
|
||||
y2="193.49992"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop style="stop-color:#ff00ff;"
|
||||
offset="0"
|
||||
id="stop876"/>
|
||||
<stop style="stop-color:#ff0000;"
|
||||
offset="1"
|
||||
id="stop878"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="m 40,120.00016 239.99984,-3.2e-4 c 0,0 24.99263,0.79932 25.00016,35.00016 0.008,34.20084 -25.00016,35 -25.00016,35 h -239.99984 c 0,-0.0205 -25,4.01348 -25,38.5 0,34.48652 25,38.5 25,38.5 h 215 c 0,0 20,-0.99604 20,-25 0,-24.00396 -20,-25 -20,-25 h -190 c 0,0 -20,1.71033 -20,25 0,24.00396 20,25 20,25 h 168.57143"/>
|
||||
</svg>
|
||||
<div class="form">
|
||||
<label for="email">用户名</label>
|
||||
<input type="email" id="email">
|
||||
<label for="password">密码</label>
|
||||
<input type="password" id="password">
|
||||
<input type="submit" id="submit" onclick="submit()" value="登 录">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var current = null;
|
||||
document.querySelector('#email').addEventListener('focus', function (e) {
|
||||
if (current) current.pause();
|
||||
current = anime({
|
||||
targets: 'path',
|
||||
strokeDashoffset: {
|
||||
value: 0,
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
},
|
||||
strokeDasharray: {
|
||||
value: '240 1386',
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
}
|
||||
});
|
||||
});
|
||||
document.querySelector('#password').addEventListener('focus', function (e) {
|
||||
if (current) current.pause();
|
||||
current = anime({
|
||||
targets: 'path',
|
||||
strokeDashoffset: {
|
||||
value: -336,
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
},
|
||||
strokeDasharray: {
|
||||
value: '240 1386',
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
}
|
||||
});
|
||||
});
|
||||
document.querySelector('#submit').addEventListener('focus', function (e) {
|
||||
if (current) current.pause();
|
||||
current = anime({
|
||||
targets: 'path',
|
||||
strokeDashoffset: {
|
||||
value: -730,
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
},
|
||||
strokeDasharray: {
|
||||
value: '530 1386',
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
}
|
||||
});
|
||||
});
|
||||
function submit() {
|
||||
let postdata = {
|
||||
"name": $("#email").val(),
|
||||
"pwd": $("#password").val(),
|
||||
};
|
||||
if (!(postdata.name && postdata.pwd)) {
|
||||
alert('参数不正确');
|
||||
return
|
||||
<script>
|
||||
var current = null;
|
||||
document.querySelector('#email').addEventListener('focus', function (e) {
|
||||
if (current) current.pause();
|
||||
current = anime({
|
||||
targets: 'path',
|
||||
strokeDashoffset: {
|
||||
value: 0,
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
},
|
||||
strokeDasharray: {
|
||||
value: '240 1386',
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
}
|
||||
$.ajax({
|
||||
url: "/api/Login/swgLogin",
|
||||
type: "POST",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
data: JSON.stringify(postdata),
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data?.result) {
|
||||
window.location.href = "/index.html";
|
||||
} else {
|
||||
alert('参数不正确');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
document.querySelector('#password').addEventListener('focus', function (e) {
|
||||
if (current) current.pause();
|
||||
current = anime({
|
||||
targets: 'path',
|
||||
strokeDashoffset: {
|
||||
value: -336,
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
},
|
||||
strokeDasharray: {
|
||||
value: '240 1386',
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
}
|
||||
});
|
||||
});
|
||||
document.querySelector('#submit').addEventListener('focus', function (e) {
|
||||
if (current) current.pause();
|
||||
current = anime({
|
||||
targets: 'path',
|
||||
strokeDashoffset: {
|
||||
value: -730,
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
},
|
||||
strokeDasharray: {
|
||||
value: '530 1386',
|
||||
duration: 700,
|
||||
easing: 'easeOutQuart'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function GetQueryString(name) {
|
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
|
||||
var r = window.location.search.substr(1).match(reg);
|
||||
if (r != null) return decodeURI(r[2]);
|
||||
return null;
|
||||
}
|
||||
|
||||
function submit() {
|
||||
let postdata = {
|
||||
"name": $("#email").val(),
|
||||
"pwd": $("#password").val(),
|
||||
};
|
||||
if (!(postdata.name && postdata.pwd)) {
|
||||
alert('参数不正确');
|
||||
return
|
||||
}
|
||||
</script>
|
||||
$.ajax({
|
||||
url: "/api/Login/swgLogin",
|
||||
type: "POST",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
data: JSON.stringify(postdata),
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data?.result) {
|
||||
var returnUrl = GetQueryString("returnUrl");
|
||||
if (returnUrl != null && returnUrl.length > 0) {
|
||||
window.location.href = returnUrl;
|
||||
} else {
|
||||
window.location.href = "/index.html";
|
||||
}
|
||||
} else {
|
||||
alert('参数不正确');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
19
Blog.Core.Common/Extensions/HttpContextExtension.cs
Normal file
19
Blog.Core.Common/Extensions/HttpContextExtension.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Blog.Core.Common.Extensions;
|
||||
|
||||
public static class HttpContextExtension
|
||||
{
|
||||
public static ISession GetSession(this HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
return context.Session;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Blog.Core.Common.Swagger;
|
||||
using Blog.Core.Model;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -51,7 +53,25 @@ namespace Blog.Core.Common.HttpContextUser
|
|||
|
||||
public string GetToken()
|
||||
{
|
||||
return _accessor.HttpContext?.Request?.Headers["Authorization"].ObjToString().Replace("Bearer ", "");
|
||||
var token = _accessor.HttpContext?.Request?.Headers["Authorization"].ObjToString().Replace("Bearer ", "");
|
||||
if (!token.IsNullOrEmpty())
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
if (_accessor.HttpContext?.IsSuccessSwagger() == true)
|
||||
{
|
||||
token = _accessor.HttpContext.GetSuccessSwaggerJwt();
|
||||
if (token.IsNotEmptyOrNull())
|
||||
{
|
||||
var claims = new ClaimsIdentity(GetClaimsIdentity(token));
|
||||
_accessor.HttpContext.User.AddIdentity(claims);
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public List<string> GetUserInfoFromToken(string ClaimType)
|
||||
|
@ -77,6 +97,10 @@ namespace Blog.Core.Common.HttpContextUser
|
|||
|
||||
public IEnumerable<Claim> GetClaimsIdentity()
|
||||
{
|
||||
if (_accessor.HttpContext == null) return ArraySegment<Claim>.Empty;
|
||||
|
||||
if (!IsAuthenticated()) return GetClaimsIdentity(GetToken());
|
||||
|
||||
var claims = _accessor.HttpContext.User.Claims.ToList();
|
||||
var headers = _accessor.HttpContext.Request.Headers;
|
||||
foreach (var header in headers)
|
||||
|
@ -86,6 +110,19 @@ namespace Blog.Core.Common.HttpContextUser
|
|||
|
||||
return claims;
|
||||
}
|
||||
public IEnumerable<Claim> GetClaimsIdentity(string token)
|
||||
{
|
||||
var jwtHandler = new JwtSecurityTokenHandler();
|
||||
// token校验
|
||||
if (token.IsNotEmptyOrNull() && jwtHandler.CanReadToken(token))
|
||||
{
|
||||
var jwtToken = jwtHandler.ReadJwtToken(token);
|
||||
|
||||
return jwtToken.Claims;
|
||||
}
|
||||
|
||||
return new List<Claim>();
|
||||
}
|
||||
|
||||
public List<string> GetClaimValueByType(string ClaimType)
|
||||
{
|
||||
|
|
48
Blog.Core.Common/Swagger/SwaggerContextExtension.cs
Normal file
48
Blog.Core.Common/Swagger/SwaggerContextExtension.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
using Blog.Core.Common.Extensions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
|
||||
namespace Blog.Core.Common.Swagger;
|
||||
|
||||
public static class SwaggerContextExtension
|
||||
{
|
||||
public const string SwaggerCodeKey = "swagger-code";
|
||||
public const string SwaggerJwt = "swagger-jwt";
|
||||
|
||||
public static bool IsSuccessSwagger()
|
||||
{
|
||||
return App.HttpContext?.GetSession()?.GetString(SwaggerCodeKey) == "success";
|
||||
}
|
||||
|
||||
public static bool IsSuccessSwagger(this HttpContext context)
|
||||
{
|
||||
return context.GetSession()?.GetString(SwaggerCodeKey) == "success";
|
||||
}
|
||||
|
||||
public static void SuccessSwagger()
|
||||
{
|
||||
App.HttpContext?.GetSession()?.SetString(SwaggerCodeKey, "success");
|
||||
}
|
||||
|
||||
public static void SuccessSwagger(this HttpContext context)
|
||||
{
|
||||
context.GetSession()?.SetString(SwaggerCodeKey, "success");
|
||||
}
|
||||
|
||||
public static void SuccessSwaggerJwt(this HttpContext context, string token)
|
||||
{
|
||||
context.GetSession()?.SetString(SwaggerJwt, token);
|
||||
}
|
||||
|
||||
public static string GetSuccessSwaggerJwt(this HttpContext context)
|
||||
{
|
||||
return context.GetSession()?.GetString(SwaggerJwt);
|
||||
}
|
||||
|
||||
|
||||
public static void RedirectSwaggerLogin(this HttpContext context)
|
||||
{
|
||||
var returnUrl = context.Request.GetDisplayUrl(); //获取当前url地址
|
||||
context.Response.Redirect("/swg-login.html?returnUrl=" + returnUrl);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ using System.Linq;
|
|||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Common.Swagger;
|
||||
using Blog.Core.Model.Models;
|
||||
|
||||
namespace Blog.Core.AuthHelper
|
||||
|
@ -116,7 +117,7 @@ namespace Blog.Core.AuthHelper
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//判断请求是否拥有凭据,即有没有登录
|
||||
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
|
||||
if (defaultAuthenticate != null)
|
||||
|
@ -127,10 +128,79 @@ namespace Blog.Core.AuthHelper
|
|||
var isTestCurrent = AppSettings.app(new string[] {"AppSettings", "UseLoadTest"}).ObjToBool();
|
||||
|
||||
//result?.Principal不为空即登录成功
|
||||
if (result?.Principal != null || isTestCurrent)
|
||||
if (result?.Principal != null || isTestCurrent || httpContext.IsSuccessSwagger())
|
||||
{
|
||||
if (!isTestCurrent) httpContext.User = result.Principal;
|
||||
|
||||
//应该要先校验用户的信息 再校验菜单权限相关的
|
||||
|
||||
//校验用户
|
||||
var user = await _userServices.QueryById(_user.ID, true);
|
||||
if (user == null)
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户不存在或已被删除").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.IsDeleted)
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被删除,禁止登陆!").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.Enable)
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被禁用!禁止登陆!").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断token是否过期,过期则重新登录
|
||||
var isExp = false;
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
isExp = (httpContext.User.Claims.FirstOrDefault(s => s.Type == "exp")?.Value) != null &&
|
||||
DateHelper.StampToDateTime(httpContext.User.Claims
|
||||
.FirstOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// jwt
|
||||
isExp =
|
||||
(httpContext.User.Claims.FirstOrDefault(s => s.Type == ClaimTypes.Expiration)
|
||||
?.Value) != null &&
|
||||
DateTime.Parse(httpContext.User.Claims
|
||||
.FirstOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
|
||||
}
|
||||
|
||||
if (!isExp)
|
||||
{
|
||||
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//校验签发时间
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
var value = httpContext.User.Claims
|
||||
.FirstOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null)
|
||||
{
|
||||
if (user.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权")
|
||||
.MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户的角色信息
|
||||
var currentUserRoles = new List<string>();
|
||||
// ids4和jwt切换
|
||||
|
@ -153,7 +223,8 @@ namespace Blog.Core.AuthHelper
|
|||
if (currentUserRoles.All(s => s != "SuperAdmin"))
|
||||
{
|
||||
var isMatchRole = false;
|
||||
var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
|
||||
var permisssionRoles =
|
||||
requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
|
||||
foreach (var item in permisssionRoles)
|
||||
{
|
||||
try
|
||||
|
@ -177,50 +248,7 @@ namespace Blog.Core.AuthHelper
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断token是否过期,过期则重新登录
|
||||
var isExp = false;
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null &&
|
||||
DateHelper.StampToDateTime(httpContext.User.Claims
|
||||
.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||
return;
|
||||
}
|
||||
|
||||
//校验签发时间
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
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.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权")
|
||||
.MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.Succeed(requirement);
|
||||
return;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Common.Swagger;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
|
@ -28,7 +29,7 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
}
|
||||
|
||||
// 无权限,跳转swagger登录页
|
||||
context.Response.Redirect("/swg-login.html");
|
||||
context.RedirectSwaggerLogin();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -40,7 +41,7 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
{
|
||||
// 使用session模式
|
||||
// 可以使用其他的
|
||||
return context.Session.GetString("swagger-code") == "success";
|
||||
return context.IsSuccessSwagger();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4,138 +4,141 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Blog.Core.Model.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户信息表
|
||||
/// </summary>
|
||||
//[SugarTable("SysUserInfo")]
|
||||
[SugarTable("SysUserInfo", "用户表")] //('数据库表名','数据库表备注')
|
||||
public class SysUserInfo : SysUserInfoRoot<long>
|
||||
{
|
||||
public SysUserInfo()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// 用户信息表
|
||||
/// </summary>
|
||||
//[SugarTable("SysUserInfo")]
|
||||
[SugarTable("SysUserInfo", "用户表")] //('数据库表名','数据库表备注')
|
||||
public class SysUserInfo : SysUserInfoRoot<long>
|
||||
{
|
||||
public SysUserInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public SysUserInfo(string loginName, string loginPWD)
|
||||
{
|
||||
LoginName = loginName;
|
||||
LoginPWD = loginPWD;
|
||||
RealName = LoginName;
|
||||
Status = 0;
|
||||
CreateTime = DateTime.Now;
|
||||
UpdateTime = DateTime.Now;
|
||||
LastErrorTime = DateTime.Now;
|
||||
ErrorCount = 0;
|
||||
Name = "";
|
||||
}
|
||||
public SysUserInfo(string loginName, string loginPWD)
|
||||
{
|
||||
LoginName = loginName;
|
||||
LoginPWD = loginPWD;
|
||||
RealName = LoginName;
|
||||
Status = 0;
|
||||
CreateTime = DateTime.Now;
|
||||
UpdateTime = DateTime.Now;
|
||||
LastErrorTime = DateTime.Now;
|
||||
ErrorCount = 0;
|
||||
Name = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录账号
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true, ColumnDescription = "登录账号")]
|
||||
//:eg model 根据sqlsugar的完整定义可以如下定义,ColumnDescription可定义表字段备注
|
||||
//[SugarColumn(IsNullable = false, ColumnDescription = "登录账号", IsPrimaryKey = false, IsIdentity = false, Length = 50)]
|
||||
//ColumnDescription 表字段备注, 已在MSSQL测试,配合 [SugarTable("SysUserInfo", "用户表")]//('数据库表名','数据库表备注')
|
||||
//可以完整生成 表备注和各个字段的中文备注
|
||||
//2022/10/11
|
||||
//测试mssql 发现 不写ColumnDescription,写好注释在mssql下也能生成表字段备注
|
||||
public string LoginName { get; set; }
|
||||
/// <summary>
|
||||
/// 登录账号
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true, ColumnDescription = "登录账号")]
|
||||
//:eg model 根据sqlsugar的完整定义可以如下定义,ColumnDescription可定义表字段备注
|
||||
//[SugarColumn(IsNullable = false, ColumnDescription = "登录账号", IsPrimaryKey = false, IsIdentity = false, Length = 50)]
|
||||
//ColumnDescription 表字段备注, 已在MSSQL测试,配合 [SugarTable("SysUserInfo", "用户表")]//('数据库表名','数据库表备注')
|
||||
//可以完整生成 表备注和各个字段的中文备注
|
||||
//2022/10/11
|
||||
//测试mssql 发现 不写ColumnDescription,写好注释在mssql下也能生成表字段备注
|
||||
public string LoginName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录密码
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string LoginPWD { get; set; }
|
||||
/// <summary>
|
||||
/// 登录密码
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string LoginPWD { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 真实姓名
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string RealName { get; set; }
|
||||
/// <summary>
|
||||
/// 真实姓名
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string RealName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部门
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int DepartmentId { get; set; } = -1;
|
||||
/// <summary>
|
||||
/// 部门
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int DepartmentId { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 2000, IsNullable = true)]
|
||||
public string Remark { get; set; }
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 2000, IsNullable = true)]
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; } = DateTime.Now;
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// 关键业务修改时间
|
||||
/// </summary>
|
||||
public DateTime CriticalModifyTime { get; set; } = DateTime.Now;
|
||||
/// <summary>
|
||||
/// 关键业务修改时间
|
||||
/// </summary>
|
||||
public DateTime CriticalModifyTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
///最后异常时间
|
||||
/// </summary>
|
||||
public DateTime LastErrorTime { get; set; } = DateTime.Now;
|
||||
/// <summary>
|
||||
///最后异常时间
|
||||
/// </summary>
|
||||
public DateTime LastErrorTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
///错误次数
|
||||
/// </summary>
|
||||
public int ErrorCount { get; set; }
|
||||
/// <summary>
|
||||
///错误次数
|
||||
/// </summary>
|
||||
public int ErrorCount { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 登录账号
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 登录账号
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string Name { get; set; }
|
||||
|
||||
// 性别
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int Sex { get; set; } = 0;
|
||||
// 性别
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int Sex { get; set; } = 0;
|
||||
|
||||
// 年龄
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int Age { get; set; }
|
||||
// 年龄
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int Age { get; set; }
|
||||
|
||||
// 生日
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public DateTime Birth { get; set; } = DateTime.Now;
|
||||
// 生日
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public DateTime Birth { get; set; } = DateTime.Now;
|
||||
|
||||
// 地址
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string Address { get; set; }
|
||||
// 地址
|
||||
[SugarColumn(Length = 200, IsNullable = true)]
|
||||
public string Address { get; set; }
|
||||
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public bool IsDeleted { get; set; }
|
||||
[SugarColumn(DefaultValue = "1")]
|
||||
public bool Enable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 租户Id
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = false,DefaultValue = "0")]
|
||||
public long TenantId { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
[Navigate(NavigateType.OneToOne, nameof(TenantId))]
|
||||
public SysTenant Tenant { get; set; }
|
||||
/// <summary>
|
||||
/// 租户Id
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = false, DefaultValue = "0")]
|
||||
public long TenantId { get; set; }
|
||||
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<string> RoleNames { get; set; }
|
||||
[Navigate(NavigateType.OneToOne, nameof(TenantId))]
|
||||
public SysTenant Tenant { get; set; }
|
||||
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<long> Dids { get; set; }
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<string> RoleNames { get; set; }
|
||||
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string DepartmentName { get; set; }
|
||||
}
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<long> Dids { get; set; }
|
||||
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string DepartmentName { get; set; }
|
||||
}
|
||||
}
|
|
@ -3,72 +3,76 @@ using Blog.Core.IServices;
|
|||
using Xunit;
|
||||
using Autofac;
|
||||
using Blog.Core.AuthHelper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Blog.Core.Tests
|
||||
{
|
||||
public class LoginController_Should
|
||||
{
|
||||
LoginController loginController;
|
||||
public class LoginController_Should
|
||||
{
|
||||
LoginController loginController;
|
||||
|
||||
private readonly ISysUserInfoServices _sysUserInfoServices;
|
||||
private readonly IUserRoleServices _userRoleServices;
|
||||
private readonly IRoleServices _roleServices;
|
||||
private readonly PermissionRequirement _requirement;
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly ISysUserInfoServices _sysUserInfoServices;
|
||||
private readonly IUserRoleServices _userRoleServices;
|
||||
private readonly IRoleServices _roleServices;
|
||||
private readonly PermissionRequirement _requirement;
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly ILogger<LoginController> _logger;
|
||||
|
||||
DI_Test dI_Test = new DI_Test();
|
||||
DI_Test dI_Test = new DI_Test();
|
||||
|
||||
|
||||
public LoginController_Should()
|
||||
{
|
||||
var container = dI_Test.DICollections();
|
||||
_sysUserInfoServices = container.Resolve<ISysUserInfoServices>();
|
||||
_userRoleServices = container.Resolve<IUserRoleServices>();
|
||||
_roleServices = container.Resolve<IRoleServices>();
|
||||
_requirement = container.Resolve<PermissionRequirement>();
|
||||
_roleModulePermissionServices = container.Resolve<IRoleModulePermissionServices>();
|
||||
_logger = container.Resolve<ILogger<LoginController>>();
|
||||
loginController = new LoginController(_sysUserInfoServices, _userRoleServices, _roleServices, _requirement,
|
||||
_roleModulePermissionServices, _logger);
|
||||
}
|
||||
|
||||
public LoginController_Should()
|
||||
{
|
||||
var container = dI_Test.DICollections();
|
||||
_sysUserInfoServices = container.Resolve<ISysUserInfoServices>();
|
||||
_userRoleServices = container.Resolve<IUserRoleServices>();
|
||||
_roleServices = container.Resolve<IRoleServices>();
|
||||
_requirement = container.Resolve<PermissionRequirement>();
|
||||
_roleModulePermissionServices = container.Resolve<IRoleModulePermissionServices>();
|
||||
loginController = new LoginController(_sysUserInfoServices,_userRoleServices,_roleServices,_requirement, _roleModulePermissionServices);
|
||||
}
|
||||
[Fact]
|
||||
public void GetJwtStrTest()
|
||||
{
|
||||
var data = loginController.GetJwtStr("test", "test");
|
||||
|
||||
[Fact]
|
||||
public void GetJwtStrTest()
|
||||
{
|
||||
var data = loginController.GetJwtStr("test", "test");
|
||||
Assert.NotNull(data);
|
||||
}
|
||||
|
||||
Assert.NotNull(data);
|
||||
}
|
||||
[Fact]
|
||||
public void GetJwtStrForNuxtTest()
|
||||
{
|
||||
object blogs = loginController.GetJwtStrForNuxt("test", "test");
|
||||
[Fact]
|
||||
public void GetJwtStrForNuxtTest()
|
||||
{
|
||||
object blogs = loginController.GetJwtStrForNuxt("test", "test");
|
||||
|
||||
Assert.NotNull(blogs);
|
||||
}
|
||||
Assert.NotNull(blogs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void GetJwtToken3Test()
|
||||
{
|
||||
[Fact]
|
||||
public async void GetJwtToken3Test()
|
||||
{
|
||||
var res = await loginController.GetJwtToken3("test", "test");
|
||||
|
||||
var res = await loginController.GetJwtToken3("test", "test");
|
||||
Assert.NotNull(res);
|
||||
}
|
||||
|
||||
Assert.NotNull(res);
|
||||
}
|
||||
[Fact]
|
||||
public async void RefreshTokenTest()
|
||||
{
|
||||
var res = await loginController.RefreshToken(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoidGVzdCIsImp0aSI6IjgiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2V4cGlyYXRpb24iOiIyMDE5LzEwLzE4IDIzOjI2OjQ5IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW5UZXN0IiwibmJmIjoxNTcxNDA4ODA5LCJleHAiOjE1NzE0MTI0MDksImlzcyI6IkJsb2cuQ29yZSIsImF1ZCI6IndyIn0.oz-SPz6UCL78fM09bUecw5rmjcNYEY9dWGtuPs2gdBg");
|
||||
|
||||
[Fact]
|
||||
public async void RefreshTokenTest()
|
||||
{
|
||||
var res = await loginController.RefreshToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoidGVzdCIsImp0aSI6IjgiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2V4cGlyYXRpb24iOiIyMDE5LzEwLzE4IDIzOjI2OjQ5IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW5UZXN0IiwibmJmIjoxNTcxNDA4ODA5LCJleHAiOjE1NzE0MTI0MDksImlzcyI6IkJsb2cuQ29yZSIsImF1ZCI6IndyIn0.oz-SPz6UCL78fM09bUecw5rmjcNYEY9dWGtuPs2gdBg");
|
||||
Assert.NotNull(res);
|
||||
}
|
||||
|
||||
Assert.NotNull(res);
|
||||
}
|
||||
[Fact]
|
||||
public void Md5PasswordTest()
|
||||
{
|
||||
var res = loginController.Md5Password("test");
|
||||
|
||||
[Fact]
|
||||
public void Md5PasswordTest()
|
||||
{
|
||||
var res = loginController.Md5Password("test");
|
||||
|
||||
Assert.NotNull(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.NotNull(res);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user