Hangfire 自帶網頁儀表板這點深得我心,是我在專案中選用它的主要原因之一。能知道排程設定狀況、執行結果,讓系統操作體驗大大加分。基於安全考量,Hangfire Dashboard 預設只開放從本機存取,如下圖所示,非本機瀏覽時會得到 HTTP 403。

所幸,Hangfire 開放客製存取權限,要改成限定 IP、登入帳號並不困難,官方文件說明得蠻清楚:Using Hangfire Dashboard,又再加分。

以下簡單示範如何開放已登入者遠端唯讀檢視。Hangfire 儀表板設定權限的做法是在 Startup UsingHangefireDashboard() 時傳入 DashboardOptions,Authorization 屬性為一 DashboardAccessAuthFilter[],需自訂一個實作 IDashboardAuthorizationFilter 的型別,在 public bool Authorize(DashboardContext context) 方法中接入 DashboardContext,傳回 true 代表允許存取,傳回 false 便會拒絕存取。DashboardContext.Request 有 Method、Path、LocalIpAddress、RemoteIpAddress 等基本屬性,但實務上還會用到 Cookie、Request.User.Identity 等作為判斷依據,做法是用 new OwinContext(DashboardContext.GetOwinEnvironment()) 轉成 OwinContext,即可取用完整 Request 資訊。至於唯讀功能,則是要寫一個 Func<DashboardContext, bool> 指派給 IsReadOnlyFunc,傳回 true 時即可關閉刪除、重跑排程或背景作業的功能。

完整程式範例如下:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using Hangfire;
using Hangfire.MemoryStorage;
using Autofac;
using Hangfire.Dashboard;
using Hangfire.Annotations;
using System.Linq;

[assembly: OwinStartup(typeof(MyWeb.Mvc.Startup))]

namespace MyWeb.Mvc
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configuration.UseMemoryStorage();
            app.UseHangfireDashboard("/hangfire", 
                new DashboardOptions
                {
                    Authorization = new [] { new DashboardAccessAuthFilter() },
                    IsReadOnlyFunc = (context) =>
                    {
                        // 由 DashboardContext 可識別使用者帳號、IP等
                        // 此處設定一律唯讀
                        return true;
                    }
                });
            app.UseHangfireServer();

            // 暫存檔管理定期排程
            TempFileManager.ScheduleTasks();

            // 基本資料定期更新
            BaseDataHelper.ScheduleTasks();
        }

        public class DashboardAccessAuthFilter : IDashboardAuthorizationFilter
        {
            public bool Authorize(DashboardContext context)
            {
                //DashboardContext.Request 提供 Method、Path、LocalIpAddress、RemoteIpAddress 等基本屬性
                var clientIp = context.Request.RemoteIpAddress;
                //不足的話,可以轉成 OwinContext
                var owinCtx = new OwinContext(context.GetOwinEnvironment());
                var isLogin = owinCtx.Request.User.Identity.IsAuthenticated;
                var loginUser = owinCtx.Request.User.Identity.Name.Split('\\').Last();
                //依據來源IP、登入帳號決定可否存取
                //例如:已登入者可存取
                return isLogin;
            }
        }
    }
}

經過這番設定,登入網站的使用即可從遠端瀏覽 Hangfire 儀表板,而原本的操作鈕,如「立即執行」「刪除」等在唯讀模式下也會消失,只剩下檢視功能。

Example of how to setting authorization and readonly of Hangfire dashboard.


Comments

Be the first to post a comment

Post a comment