From 3a43a2205a68bb92401c7a7d7acfc5ca208358c2 Mon Sep 17 00:00:00 2001 From: chfei Date: Mon, 12 Oct 2026 16:27:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KJD_WebService/Startup.cs | 77 ++++++++++++++++++- KJD_WebService/Web.config | 4 +- .../DependencyInjection/ContainerConfig.cs | 6 +- 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/KJD_WebService/Startup.cs b/KJD_WebService/Startup.cs index 096d69c..cb9d924 100644 --- a/KJD_WebService/Startup.cs +++ b/KJD_WebService/Startup.cs @@ -1,13 +1,21 @@ using Autofac; using FreeSql; +using Hangfire; +using Hangfire.Dashboard; using KJD_Web.Repository; using MAX.Core.DependencyInjection; using MAX.Core.Interfaces; +using Microsoft.Owin; +using Owin; using System; using System.Collections.Generic; +using System.Configuration; using System.Linq; +using System.Security.Cryptography; +using System.Text; using System.Web; +[assembly: OwinStartup(typeof(KJD_Web.Startup))] namespace KJD_Web; public class Startup : IStartup @@ -16,7 +24,7 @@ public class Startup : IStartup public void Initialize() { - + } public void Register(IServiceRegistrar registrar) @@ -27,4 +35,71 @@ public class Startup : IStartup .InstancePerRequest(); } + public void Configuration(IAppBuilder app) + { + app.UseHangfireDashboard("/hangfire", new DashboardOptions + { + Authorization = new[] + { + new BasicAuthDashboardAuthorizationFilter( + ConfigurationManager.AppSettings["Hangfire:User"], + ConfigurationManager.AppSettings["Hangfire:Password"]) + } + }); + } +} +public class BasicAuthDashboardAuthorizationFilter : IDashboardAuthorizationFilter +{ + private readonly string _user; + private readonly string _password; + + public BasicAuthDashboardAuthorizationFilter(string user, string password) + { + _user = user; + _password = password; + } + + public bool Authorize(DashboardContext context) + { + var owinContext = new OwinContext(((OwinDashboardContext)context).Environment); + var response = owinContext.Response; + + // 未配置账号密码时一律拒绝,避免误开放 + if (string.IsNullOrEmpty(_user) || string.IsNullOrEmpty(_password)) + return false; + + var header = owinContext.Request.Headers["Authorization"]; + if (!string.IsNullOrEmpty(header) && + header.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase)) + { + try + { + var raw = Encoding.UTF8.GetString(Convert.FromBase64String(header.Substring(6).Trim())); + var idx = raw.IndexOf(':'); + if (idx > 0) + { + var user = raw.Substring(0, idx); + var pwd = raw.Substring(idx + 1); + + // 常量时间比较,防止时序攻击 + if (SafeEquals(user, _user) & SafeEquals(pwd, _password)) + return true; + } + } + catch (FormatException) { /* Base64 非法,按未通过处理 */ } + } + + // 触发浏览器弹出账号密码框 + response.Headers["WWW-Authenticate"] = "Basic realm=\"Hangfire Dashboard\""; + return false; // Hangfire 会随后返回 401 + } + + private static bool SafeEquals(string a, string b) + { + var ha = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(a ?? "")); + var hb = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(b ?? "")); + var diff = 0; + for (var i = 0; i < ha.Length; i++) diff |= ha[i] ^ hb[i]; + return diff == 0; + } } \ No newline at end of file diff --git a/KJD_WebService/Web.config b/KJD_WebService/Web.config index 5ffe245..01af2dc 100644 --- a/KJD_WebService/Web.config +++ b/KJD_WebService/Web.config @@ -28,7 +28,9 @@ - + + +