mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
Merge branch 'master' into net7.0
This commit is contained in:
commit
f786881e89
|
@ -15,324 +15,332 @@ using Serilog;
|
||||||
|
|
||||||
namespace Blog.Core.Controllers
|
namespace Blog.Core.Controllers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录管理【无权限】
|
/// 登录管理【无权限】
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
[Route("api/Login")]
|
[Route("api/Login")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public class LoginController : BaseApiController
|
public class LoginController : BaseApiController
|
||||||
{
|
{
|
||||||
readonly ISysUserInfoServices _sysUserInfoServices;
|
readonly ISysUserInfoServices _sysUserInfoServices;
|
||||||
readonly IUserRoleServices _userRoleServices;
|
readonly IUserRoleServices _userRoleServices;
|
||||||
readonly IRoleServices _roleServices;
|
readonly IRoleServices _roleServices;
|
||||||
readonly PermissionRequirement _requirement;
|
readonly PermissionRequirement _requirement;
|
||||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||||
private readonly ILogger<LoginController> _logger;
|
private readonly ILogger<LoginController> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数注入
|
/// 构造函数注入
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sysUserInfoServices"></param>
|
/// <param name="sysUserInfoServices"></param>
|
||||||
/// <param name="userRoleServices"></param>
|
/// <param name="userRoleServices"></param>
|
||||||
/// <param name="roleServices"></param>
|
/// <param name="roleServices"></param>
|
||||||
/// <param name="requirement"></param>
|
/// <param name="requirement"></param>
|
||||||
/// <param name="roleModulePermissionServices"></param>
|
/// <param name="roleModulePermissionServices"></param>
|
||||||
public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices,
|
public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices,
|
||||||
IRoleServices roleServices, PermissionRequirement requirement,
|
IRoleServices roleServices, PermissionRequirement requirement,
|
||||||
IRoleModulePermissionServices roleModulePermissionServices, ILogger<LoginController> logger)
|
IRoleModulePermissionServices roleModulePermissionServices, ILogger<LoginController> logger)
|
||||||
{
|
{
|
||||||
this._sysUserInfoServices = sysUserInfoServices;
|
this._sysUserInfoServices = sysUserInfoServices;
|
||||||
this._userRoleServices = userRoleServices;
|
this._userRoleServices = userRoleServices;
|
||||||
this._roleServices = roleServices;
|
this._roleServices = roleServices;
|
||||||
_requirement = requirement;
|
_requirement = requirement;
|
||||||
_roleModulePermissionServices = roleModulePermissionServices;
|
_roleModulePermissionServices = roleModulePermissionServices;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region 获取token的第1种方法
|
#region 获取token的第1种方法
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取JWT的方法1
|
/// 获取JWT的方法1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="pass"></param>
|
/// <param name="pass"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Token")]
|
[Route("Token")]
|
||||||
public async Task<MessageModel<string>> GetJwtStr(string name, string pass)
|
public async Task<MessageModel<string>> GetJwtStr(string name, string pass)
|
||||||
{
|
{
|
||||||
string jwtStr = string.Empty;
|
string jwtStr = string.Empty;
|
||||||
bool suc = false;
|
bool suc = false;
|
||||||
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
||||||
|
|
||||||
var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
|
var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
TokenModelJwt tokenModel = new TokenModelJwt {Uid = 1, Role = user};
|
TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = user };
|
||||||
|
|
||||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||||
suc = true;
|
suc = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jwtStr = "login fail!!!";
|
jwtStr = "login fail!!!";
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MessageModel<string>()
|
return new MessageModel<string>()
|
||||||
{
|
{
|
||||||
success = suc,
|
success = suc,
|
||||||
msg = suc ? "获取成功" : "获取失败",
|
msg = suc ? "获取成功" : "获取失败",
|
||||||
response = jwtStr
|
response = jwtStr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取JWT的方法2:给Nuxt提供
|
/// 获取JWT的方法2:给Nuxt提供
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="pass"></param>
|
/// <param name="pass"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("GetTokenNuxt")]
|
[Route("GetTokenNuxt")]
|
||||||
public MessageModel<string> GetJwtStrForNuxt(string name, string pass)
|
public MessageModel<string> GetJwtStrForNuxt(string name, string pass)
|
||||||
{
|
{
|
||||||
string jwtStr = string.Empty;
|
string jwtStr = string.Empty;
|
||||||
bool suc = false;
|
bool suc = false;
|
||||||
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
|
||||||
//这里直接写死了
|
//这里直接写死了
|
||||||
if (name == "admins" && pass == "admins")
|
if (name == "admins" && pass == "admins")
|
||||||
{
|
{
|
||||||
TokenModelJwt tokenModel = new TokenModelJwt
|
TokenModelJwt tokenModel = new TokenModelJwt
|
||||||
{
|
{
|
||||||
Uid = 1,
|
Uid = 1,
|
||||||
Role = "Admin"
|
Role = "Admin"
|
||||||
};
|
};
|
||||||
|
|
||||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||||
suc = true;
|
suc = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jwtStr = "login fail!!!";
|
jwtStr = "login fail!!!";
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = new
|
var result = new
|
||||||
{
|
{
|
||||||
data = new {success = suc, token = jwtStr}
|
data = new { success = suc, token = jwtStr }
|
||||||
};
|
};
|
||||||
|
|
||||||
return new MessageModel<string>()
|
return new MessageModel<string>()
|
||||||
{
|
{
|
||||||
success = suc,
|
success = suc,
|
||||||
msg = suc ? "获取成功" : "获取失败",
|
msg = suc ? "获取成功" : "获取失败",
|
||||||
response = jwtStr
|
response = jwtStr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取JWT的方法3:整个系统主要方法
|
/// 获取JWT的方法3:整个系统主要方法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="pass"></param>
|
/// <param name="pass"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("JWTToken3.0")]
|
[Route("JWTToken3.0")]
|
||||||
public async Task<MessageModel<TokenInfoViewModel>> GetJwtToken3(string name = "", string pass = "")
|
public async Task<MessageModel<TokenInfoViewModel>> GetJwtToken3(string name = "", string pass = "")
|
||||||
|
|
||||||
{
|
|
||||||
string jwtStr = string.Empty;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
|
{
|
||||||
return Failed<TokenInfoViewModel>("用户名或密码不能为空");
|
string jwtStr = string.Empty;
|
||||||
|
|
||||||
pass = MD5Helper.MD5Encrypt32(pass);
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
|
||||||
|
return Failed<TokenInfoViewModel>("用户名或密码不能为空");
|
||||||
|
|
||||||
var user = await _sysUserInfoServices.Query(d =>
|
pass = MD5Helper.MD5Encrypt32(pass);
|
||||||
d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false);
|
|
||||||
if (user.Count > 0)
|
var user = await _sysUserInfoServices.Query(d =>
|
||||||
{
|
d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false);
|
||||||
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
|
if (user.Count > 0)
|
||||||
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
{
|
||||||
var claims = new List<Claim>
|
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
|
||||||
{
|
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
||||||
new Claim(ClaimTypes.Name, name),
|
var claims = new List<Claim>
|
||||||
new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
|
{
|
||||||
new Claim("TenantId", user.FirstOrDefault().TenantId.ToString()),
|
new Claim(ClaimTypes.Name, name),
|
||||||
new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
|
new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
|
||||||
new Claim(ClaimTypes.Expiration,
|
new Claim("TenantId", user.FirstOrDefault().TenantId.ToString()),
|
||||||
DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
|
new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
|
||||||
};
|
new Claim(ClaimTypes.Expiration,
|
||||||
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
|
||||||
|
};
|
||||||
|
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
||||||
|
|
||||||
|
|
||||||
// ids4和jwt切换
|
// ids4和jwt切换
|
||||||
// jwt
|
// jwt
|
||||||
if (!Permissions.IsUseIds4)
|
if (!Permissions.IsUseIds4)
|
||||||
{
|
{
|
||||||
var data = await _roleModulePermissionServices.RoleModuleMaps();
|
var data = await _roleModulePermissionServices.RoleModuleMaps();
|
||||||
var list = (from item in data
|
var list = (from item in data
|
||||||
where item.IsDeleted == false
|
where item.IsDeleted == false
|
||||||
orderby item.Id
|
orderby item.Id
|
||||||
select new PermissionItem
|
select new PermissionItem
|
||||||
{
|
{
|
||||||
Url = item.Module?.LinkUrl,
|
Url = item.Module?.LinkUrl,
|
||||||
Role = item.Role?.Name.ObjToString(),
|
Role = item.Role?.Name.ObjToString(),
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
_requirement.Permissions = list;
|
_requirement.Permissions = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||||
return Success(token, "获取成功");
|
return Success(token, "获取成功");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Failed<TokenInfoViewModel>("认证失败");
|
return Failed<TokenInfoViewModel>("认证失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[HttpGet]
|
||||||
/// 请求刷新Token(以旧换新)
|
[Route("GetJwtTokenSecret")]
|
||||||
/// </summary>
|
public async Task<MessageModel<TokenInfoViewModel>> GetJwtTokenSecret(string name = "", string pass = "")
|
||||||
/// <param name="token"></param>
|
{
|
||||||
/// <returns></returns>
|
var rlt = await GetJwtToken3(name, pass);
|
||||||
[HttpGet]
|
return rlt;
|
||||||
[Route("RefreshToken")]
|
}
|
||||||
public async Task<MessageModel<TokenInfoViewModel>> RefreshToken(string token = "")
|
|
||||||
{
|
|
||||||
string jwtStr = string.Empty;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(token))
|
/// <summary>
|
||||||
return Failed<TokenInfoViewModel>("token无效,请重新登录!");
|
/// 请求刷新Token(以旧换新)
|
||||||
var tokenModel = JwtHelper.SerializeJwt(token);
|
/// </summary>
|
||||||
if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
|
/// <param name="token"></param>
|
||||||
{
|
/// <returns></returns>
|
||||||
var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
|
[HttpGet]
|
||||||
var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
[Route("RefreshToken")]
|
||||||
if (value != null && user.CriticalModifyTime > value.ObjToDate())
|
public async Task<MessageModel<TokenInfoViewModel>> RefreshToken(string token = "")
|
||||||
{
|
{
|
||||||
return Failed<TokenInfoViewModel>("很抱歉,授权已失效,请重新授权!");
|
string jwtStr = string.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate()))
|
if (string.IsNullOrEmpty(token))
|
||||||
{
|
return Failed<TokenInfoViewModel>("token无效,请重新登录!");
|
||||||
var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.LoginName, user.LoginPWD);
|
var tokenModel = JwtHelper.SerializeJwt(token);
|
||||||
//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
|
if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
|
||||||
var claims = new List<Claim>
|
{
|
||||||
{
|
var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
|
||||||
new Claim(ClaimTypes.Name, user.LoginName),
|
var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||||
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
|
if (value != null && user.CriticalModifyTime > value.ObjToDate())
|
||||||
new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
|
{
|
||||||
new Claim(ClaimTypes.Expiration,
|
return Failed<TokenInfoViewModel>("很抱歉,授权已失效,请重新授权!");
|
||||||
DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
|
}
|
||||||
};
|
|
||||||
claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
|
||||||
|
|
||||||
//用户标识
|
if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate()))
|
||||||
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
|
{
|
||||||
identity.AddClaims(claims);
|
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 refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
//用户标识
|
||||||
return Success(refreshToken, "获取成功");
|
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
|
||||||
}
|
identity.AddClaims(claims);
|
||||||
}
|
|
||||||
|
|
||||||
return Failed<TokenInfoViewModel>("认证失败!");
|
var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||||
}
|
return Success(refreshToken, "获取成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
return Failed<TokenInfoViewModel>("认证失败!");
|
||||||
/// 获取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);
|
/// <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 response = string.Format("\"value\":\"{0}\"", jwtStr);
|
string jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||||
string call = callBack + "({" + response + "})";
|
|
||||||
Response.WriteAsync(call);
|
string response = string.Format("\"value\":\"{0}\"", jwtStr);
|
||||||
}
|
string call = callBack + "({" + response + "})";
|
||||||
|
Response.WriteAsync(call);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 测试 MD5 加密字符串
|
/// 测试 MD5 加密字符串
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="password"></param>
|
/// <param name="password"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Md5Password")]
|
[Route("Md5Password")]
|
||||||
public string Md5Password(string password = "")
|
public string Md5Password(string password = "")
|
||||||
{
|
{
|
||||||
return MD5Helper.MD5Encrypt32(password);
|
return MD5Helper.MD5Encrypt32(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// swagger登录
|
/// swagger登录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="loginRequest"></param>
|
/// <param name="loginRequest"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("/api/Login/swgLogin")]
|
[Route("/api/Login/swgLogin")]
|
||||||
public async Task<dynamic> SwgLogin([FromBody] SwaggerLoginRequest loginRequest)
|
public async Task<dynamic> SwgLogin([FromBody] SwaggerLoginRequest loginRequest)
|
||||||
{
|
{
|
||||||
if (loginRequest is null)
|
if (loginRequest is null)
|
||||||
{
|
{
|
||||||
return new {result = false};
|
return new { result = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await GetJwtToken3(loginRequest.name, loginRequest.pwd);
|
var result = await GetJwtToken3(loginRequest.name, loginRequest.pwd);
|
||||||
if (result.success)
|
if (result.success)
|
||||||
{
|
{
|
||||||
HttpContext.SuccessSwagger();
|
HttpContext.SuccessSwagger();
|
||||||
HttpContext.SuccessSwaggerJwt(result.response.token);
|
HttpContext.SuccessSwaggerJwt(result.response.token);
|
||||||
return new {result = true};
|
return new { result = true };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogWarning(ex, "Swagger登录异常");
|
_logger.LogWarning(ex, "Swagger登录异常");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new {result = false};
|
return new { result = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// weixin登录
|
/// weixin登录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("wxLogin")]
|
[Route("wxLogin")]
|
||||||
public dynamic WxLogin(string g = "", string token = "")
|
public dynamic WxLogin(string g = "", string token = "")
|
||||||
{
|
{
|
||||||
return new {g, token};
|
return new { g, token };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SwaggerLoginRequest
|
public class SwaggerLoginRequest
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string pwd { get; set; }
|
public string pwd { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -144,6 +144,9 @@ else
|
||||||
//app.UseHsts();
|
//app.UseHsts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.UseEncryptionRequest();
|
||||||
|
app.UseEncryptionResponse();
|
||||||
|
|
||||||
app.UseExceptionHandlerMiddle();
|
app.UseExceptionHandlerMiddle();
|
||||||
app.UseIpLimitMiddle();
|
app.UseIpLimitMiddle();
|
||||||
app.UseRequestResponseLogMiddle();
|
app.UseRequestResponseLogMiddle();
|
||||||
|
|
|
@ -265,6 +265,20 @@
|
||||||
},
|
},
|
||||||
"IpRateLimit": {
|
"IpRateLimit": {
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
|
},
|
||||||
|
"EncryptionResponse": {
|
||||||
|
"Enabled": true,
|
||||||
|
"AllApis": false,
|
||||||
|
"LimitApis": [
|
||||||
|
"/api/Login/GetJwtTokenSecret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"EncryptionRequest": {
|
||||||
|
"Enabled": true,
|
||||||
|
"AllApis": false,
|
||||||
|
"LimitApis": [
|
||||||
|
"/api/Login/GetJwtTokenSecret"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"IpRateLimiting": {
|
"IpRateLimiting": {
|
||||||
|
|
|
@ -7,29 +7,29 @@ namespace Blog.Core.Common.Extensions;
|
||||||
|
|
||||||
public static class HttpResponseExceptions
|
public static class HttpResponseExceptions
|
||||||
{
|
{
|
||||||
public static string GetResponseBody(this HttpResponse response)
|
public static string GetResponseBody(this HttpResponse response)
|
||||||
{
|
{
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
return default;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.Body is FluentHttpResponseStream responseBody)
|
//原始HttpResponseStream 无法读取
|
||||||
{
|
//实际上只是个包装类,内部使用了HttpResponsePipeWriter write
|
||||||
response.Body.Position = 0;
|
switch (response.Body)
|
||||||
//不关闭底层流
|
{
|
||||||
using StreamReader stream = new StreamReader(responseBody, leaveOpen: true);
|
case FluentHttpResponseStream:
|
||||||
string body = stream.ReadToEnd();
|
case MemoryStream:
|
||||||
response.Body.Position = 0;
|
{
|
||||||
return body;
|
response.Body.Position = 0;
|
||||||
}
|
using var stream = new StreamReader(response.Body, leaveOpen: true);
|
||||||
else
|
var body = stream.ReadToEnd();
|
||||||
{
|
response.Body.Position = 0;
|
||||||
//原始HttpResponseStream 无法读取
|
return body;
|
||||||
//实际上只是个包装类,内部使用了HttpResponsePipeWriter write
|
}
|
||||||
throw new ApplicationException("The response body is not a FluentHttpResponseStream");
|
default:
|
||||||
}
|
// throw new ApplicationException("The response body is not a FluentHttpResponseStream");
|
||||||
|
return string.Empty;
|
||||||
return default;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
116
Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
Normal file
116
Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
using Blog.Core.Common;
|
||||||
|
using Blog.Core.Common.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Blog.Core.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义中间件
|
||||||
|
/// 通过配置,对指定接口返回数据进行加密返回
|
||||||
|
/// 可过滤文件流
|
||||||
|
/// </summary>
|
||||||
|
public class EncryptionRequestMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
|
||||||
|
public EncryptionRequestMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
// 配置开关,过滤接口
|
||||||
|
if (AppSettings.app("Middleware", "EncryptionRequest", "Enabled").ObjToBool())
|
||||||
|
{
|
||||||
|
var isAllApis = AppSettings.app("Middleware", "EncryptionRequest", "AllApis").ObjToBool();
|
||||||
|
var needEnApis = AppSettings.app<string>("Middleware", "EncryptionRequest", "LimitApis");
|
||||||
|
var path = context.Request.Path.Value.ToLower();
|
||||||
|
if (isAllApis || (path.Length > 5 && needEnApis.Any(d => d.ToLower().Contains(path))))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{isAllApis} -- {path}");
|
||||||
|
|
||||||
|
if (context.Request.Method.ToLower() == "post")
|
||||||
|
{
|
||||||
|
// 读取请求主体
|
||||||
|
using StreamReader reader = new(context.Request.Body, Encoding.UTF8);
|
||||||
|
string requestBody = await reader.ReadToEndAsync();
|
||||||
|
|
||||||
|
// 检查是否有要解密的数据
|
||||||
|
if (!string.IsNullOrEmpty(requestBody) && context.Request.Headers.ContainsKey("Content-Type") &&
|
||||||
|
context.Request.Headers["Content-Type"].ToString().ToLower().Contains("application/json"))
|
||||||
|
{
|
||||||
|
// 解密数据
|
||||||
|
string decryptedString = DecryptData(requestBody);
|
||||||
|
|
||||||
|
// 更新请求主体中的数据
|
||||||
|
context.Request.Body = GenerateStreamFromString(decryptedString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (context.Request.Method.ToLower() == "get")
|
||||||
|
{
|
||||||
|
// 获取url参数
|
||||||
|
string param = context.Request.Query["param"];
|
||||||
|
|
||||||
|
// 检查是否有要解密的数据
|
||||||
|
if (!string.IsNullOrEmpty(param))
|
||||||
|
{
|
||||||
|
// 解密数据
|
||||||
|
string decryptedString = DecryptData(param);
|
||||||
|
|
||||||
|
// 更新url参数值
|
||||||
|
context.Request.QueryString = new QueryString($"?{decryptedString}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string DecryptData(string encryptedData)
|
||||||
|
{
|
||||||
|
// 解密逻辑实现,可以根据你使用的加密算法和密钥进行自定义
|
||||||
|
byte[] bytes = Convert.FromBase64String(encryptedData);
|
||||||
|
string originalString = Encoding.UTF8.GetString(bytes);
|
||||||
|
Console.WriteLine(originalString);
|
||||||
|
return originalString;
|
||||||
|
}
|
||||||
|
private static Stream GenerateStreamFromString(string s)
|
||||||
|
{
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
var writer = new StreamWriter(stream);
|
||||||
|
writer.Write(s);
|
||||||
|
writer.Flush();
|
||||||
|
stream.Position = 0;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EncryptionRequestExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义中间件
|
||||||
|
/// 通过配置,对指定接口入参进行解密操作
|
||||||
|
/// 注意:放到管道最外层
|
||||||
|
/// </summary>
|
||||||
|
public static IApplicationBuilder UseEncryptionRequest(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.UseMiddleware<EncryptionRequestMiddleware>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
Normal file
118
Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
using Blog.Core.Common;
|
||||||
|
using Blog.Core.Common.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Blog.Core.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义中间件
|
||||||
|
/// 通过配置,对指定接口返回数据进行加密返回
|
||||||
|
/// 可过滤文件流
|
||||||
|
/// </summary>
|
||||||
|
public class EncryptionResponseMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
|
||||||
|
public EncryptionResponseMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
// 配置开关,过滤接口
|
||||||
|
if (AppSettings.app("Middleware", "EncryptionResponse", "Enabled").ObjToBool())
|
||||||
|
{
|
||||||
|
var isAllApis = AppSettings.app("Middleware", "EncryptionResponse", "AllApis").ObjToBool();
|
||||||
|
var needEnApis = AppSettings.app<string>("Middleware", "EncryptionResponse", "LimitApis");
|
||||||
|
var path = context.Request.Path.Value.ToLower();
|
||||||
|
if (isAllApis || (path.Length > 5 && needEnApis.Any(d => d.ToLower().Contains(path))))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{isAllApis} -- {path}");
|
||||||
|
var responseCxt = context.Response;
|
||||||
|
var originalBodyStream = responseCxt.Body;
|
||||||
|
|
||||||
|
// 创建一个新的内存流用于存储加密后的数据
|
||||||
|
using var encryptedBodyStream = new MemoryStream();
|
||||||
|
// 用新的内存流替换 responseCxt.Body
|
||||||
|
responseCxt.Body = encryptedBodyStream;
|
||||||
|
|
||||||
|
// 执行下一个中间件请求管道
|
||||||
|
await _next(context);
|
||||||
|
|
||||||
|
//encryptedBodyStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
//encryptedBodyStream.Position = 0;
|
||||||
|
|
||||||
|
// 可以去掉某些流接口
|
||||||
|
if (!context.Response.ContentType.ToLower().Contains("application/json"))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"非json返回格式 {context.Response.ContentType}");
|
||||||
|
//await encryptedBodyStream.CopyToAsync(originalBodyStream);
|
||||||
|
context.Response.Body = originalBodyStream;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取加密后的数据
|
||||||
|
//var encryptedBody = await new StreamReader(encryptedBodyStream).ReadToEndAsync();
|
||||||
|
var encryptedBody = responseCxt.GetResponseBody();
|
||||||
|
|
||||||
|
if (encryptedBody.IsNotEmptyOrNull())
|
||||||
|
{
|
||||||
|
dynamic jsonObject = JsonConvert.DeserializeObject(encryptedBody);
|
||||||
|
string statusCont = jsonObject.status;
|
||||||
|
var status = statusCont.ObjToInt();
|
||||||
|
string msg = jsonObject.msg;
|
||||||
|
string successCont = jsonObject.success;
|
||||||
|
var success = successCont.ObjToBool();
|
||||||
|
dynamic responseCnt = success ? jsonObject.response : "";
|
||||||
|
string s = "1";
|
||||||
|
// 这里换成自己的任意加密方式
|
||||||
|
var response = responseCnt.ToString() != "" ? Convert.ToBase64String(Encoding.UTF8.GetBytes(responseCnt.ToString())) : "";
|
||||||
|
string resJson = JsonConvert.SerializeObject(new { response, msg, status, s, success });
|
||||||
|
|
||||||
|
context.Response.Clear();
|
||||||
|
responseCxt.ContentType = "application/json";
|
||||||
|
|
||||||
|
//await using var streamlriter = new StreamWriter(originalBodyStream, leaveOpen: true);
|
||||||
|
//await streamlriter.WriteAsync(resJson);
|
||||||
|
|
||||||
|
var encryptedData = Encoding.UTF8.GetBytes(resJson);
|
||||||
|
responseCxt.ContentLength = encryptedData.Length;
|
||||||
|
await originalBodyStream.WriteAsync(encryptedData, 0, encryptedData.Length);
|
||||||
|
|
||||||
|
responseCxt.Body = originalBodyStream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EncryptionResponseExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义中间件
|
||||||
|
/// 通过配置,对指定接口返回数据进行加密返回
|
||||||
|
/// 可过滤文件流
|
||||||
|
/// 注意:放到管道最外层
|
||||||
|
/// </summary>
|
||||||
|
public static IApplicationBuilder UseEncryptionResponse(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.UseMiddleware<EncryptionResponseMiddleware>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -96,11 +96,11 @@ namespace Blog.Core.Extensions.Middlewares
|
||||||
|
|
||||||
// 去除 Html
|
// 去除 Html
|
||||||
var reg = "<[^>]+>";
|
var reg = "<[^>]+>";
|
||||||
var isHtml = Regex.IsMatch(responseBody, reg);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(responseBody))
|
if (!string.IsNullOrEmpty(responseBody))
|
||||||
{
|
{
|
||||||
Parallel.For(0, 1, e =>
|
var isHtml = Regex.IsMatch(responseBody, reg);
|
||||||
|
Parallel.For(0, 1, e =>
|
||||||
{
|
{
|
||||||
//LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
|
//LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
|
||||||
LogLock.OutLogAOP("RequestResponseLog", response.HttpContext.TraceIdentifier,
|
LogLock.OutLogAOP("RequestResponseLog", response.HttpContext.TraceIdentifier,
|
||||||
|
|
|
@ -83,10 +83,12 @@ namespace Blog.Core.Extensions
|
||||||
{
|
{
|
||||||
BaseDBConfig.MainConfig = config;
|
BaseDBConfig.MainConfig = config;
|
||||||
}
|
}
|
||||||
|
else if (m.ConnId.ToLower().StartsWith(MainDb.CurrentDbConnId.ToLower()))
|
||||||
//复用连接
|
{
|
||||||
if (m.ConnId.ToLower().StartsWith(MainDb.CurrentDbConnId.ToLower()))
|
//复用连接
|
||||||
BaseDBConfig.ReuseConfigs.Add(config);
|
BaseDBConfig.ReuseConfigs.Add(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BaseDBConfig.ValidConfig.Add(config);
|
BaseDBConfig.ValidConfig.Add(config);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user