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; } } }