using System.Net;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Authentication;
using Tiobon.Core.Common;
using Tiobon.Core.Common.Caches;
using Tiobon.Core.Common.Helper;
namespace Tiobon.Core.AuthHelper
{
///
/// 中间件
/// 原做为自定义授权中间件
/// 先做检查 header token的使用
///
public class CustomJwtTokenAuthMiddleware
{
private readonly ICaching _cache;
///
/// 验证方案提供对象
///
public IAuthenticationSchemeProvider Schemes { get; set; }
///
/// 请求上下文
///
private readonly RequestDelegate _next;
public CustomJwtTokenAuthMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes, AppSettings appset,ICaching cache)
{
_cache = cache;
_next = next;
Schemes = schemes;
}
///
/// 网关授权
///
///
///
public async Task Invoke(HttpContext httpContext)
{
var questUrl = httpContext?.Request.Path.Value.ToLower();
if (string.IsNullOrEmpty(questUrl)) return;
//白名单验证
if (CheckWhiteList(questUrl))
{
await _next.Invoke(httpContext);
return;
}
//黑名单验证
if(CheckBlackList(questUrl))
{
return;
}
List Permissions= new();
httpContext.Features.Set(new AuthenticationFeature
{
OriginalPath = httpContext.Request.Path,
OriginalPathBase = httpContext.Request.PathBase
});
//判断请求是否拥有凭据,即有没有登录
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
if (defaultAuthenticate != null)
{
var Authresult = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
if (Authresult?.Principal != null)
{
httpContext.User = Authresult.Principal;
// 获取当前用户的角色信息
var currentUserRoles = (from item in httpContext.User.Claims
where item.Type == "CofRole"
select item.Value).ToList();
var isMatchRole = false;
var permisssionRoles = Permissions.Where(w => currentUserRoles.Contains(w.Role));
foreach (var item in permisssionRoles)
{
try
{
if (Regex.IsMatch(questUrl, item.Url, RegexOptions.IgnoreCase))
{
isMatchRole = true;
break;
}
}
catch (Exception)
{
// ignored
}
}
//验证权限
if (currentUserRoles.Count <= 0 || !isMatchRole)
{
await httpContext.Cof_SendResponse(HttpStatusCode.ServiceUnavailable, "未授权此资源");
return ;
}
}
else
{
await httpContext.Cof_SendResponse(HttpStatusCode.Unauthorized, "请重新登录");
return ;
}
}
else
{
await httpContext.Cof_SendResponse(HttpStatusCode.Unauthorized, "系统鉴权出错");
return ;
}
await _next.Invoke(httpContext);
}
///
/// 返回相应
///
///
///
///
///
private async Task SendResponse(HttpContext context, string message, HttpStatusCode code)
{
context.Response.StatusCode = (int)code;
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync(message);
}
///
/// 判断是否在白名单内,支持通配符 ****
///
///
///
public bool CheckWhiteList(string url)
{
List WhiteList = _cache.Cof_GetICaching>("WhiteList", () => AppSettings.app("WhiteList"), 10);
if (!WhiteList.Cof_CheckAvailable()) return false;
foreach (var Urlitem in WhiteList)
{
if (Urlitem.url.Equals(url, StringComparison.OrdinalIgnoreCase)) return true;
if (Urlitem.url.IndexOf("****") > 0)
{
string UrlitemP = Urlitem.url.Replace("****", "");
if (Regex.IsMatch(url, UrlitemP, RegexOptions.IgnoreCase)) return true;
if (url.Length >= UrlitemP.Length && UrlitemP.ToLower() == url.Substring(0, UrlitemP.Length).ToLower()) return true;
}
}
return false;
}
public bool CheckBlackList(string url)
{
List BlackList = _cache.Cof_GetICaching>("BlackList", () => AppSettings.app("BlackList"), 10);
if (!BlackList.Cof_CheckAvailable()) return false;
foreach (var Urlitem in BlackList)
{
if (Urlitem.url.Equals(url, StringComparison.OrdinalIgnoreCase)) return true;
if (Urlitem.url.IndexOf("****") > 0)
{
string UrlitemP = Urlitem.url.Replace("****", "");
if (Regex.IsMatch(url, UrlitemP, RegexOptions.IgnoreCase)) return true;
if (url.Length >= UrlitemP.Length && UrlitemP.ToLower() == url.Substring(0, UrlitemP.Length).ToLower()) return true;
}
}
return false;
}
}
public class Urlobj
{
public string url { get; set; }
}
}