關於 hangfire 的權限問題


hangfire 是一個分布式后台執行服務。

官網:http://hangfire.io/

 

我看中hangfire的地方是

1:使用簡單

2:多種持久化保存方案。支持sqlserver ,msmq等 ,其他的redis 等持久化方案要收費。不過自己擴展不是難事。hangfire基於net3.5的extension擴展。

3:有監控系統,並且可以和其他監控系統集成。 

 

回顧正題:

hangfire在部署到iis環境上,通過地址訪問的時候會出現401未授權錯誤。通過代碼分析是由於hangfire內建授權機制造成的問題。

在分析源碼前,建議先對owin做個了解:

http://www.cnblogs.com/dudu/p/what-is-owin.html

http://owin.org/

hangfire繼承了OwinMiddleware,在每次請求的時候會去執行IAuthorizationFilter的實現。

   internal class DashboardMiddleware : OwinMiddleware
    {
        private readonly JobStorage _storage;
        private readonly RouteCollection _routes;
        private readonly IEnumerable<IAuthorizationFilter> _authorizationFilters;

     
        public override Task Invoke(IOwinContext context)
        {
            var dispatcher = _routes.FindDispatcher(context.Request.Path.Value);
            
            if (dispatcher == null)
            {
                return Next.Invoke(context);
            }
             
            foreach (var filter in _authorizationFilters)
            {
                if (!filter.Authorize(context.Environment))
                {
                    context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
                    return Task.FromResult(false);
                }
            }

            var dispatcherContext = new RequestDispatcherContext(
                _storage,
                context.Environment,
                dispatcher.Item2);

            return dispatcher.Item1.Dispatch(dispatcherContext);
        }
    }

 

hangfire默認加載了 LocalRequestsOnlyAuthorizationFilter 

    public class LocalRequestsOnlyAuthorizationFilter : IAuthorizationFilter
    {
        public bool Authorize(IDictionary<string, object> owinEnvironment)
        {
            var context = new OwinContext(owinEnvironment);
            var remoteAddress = context.Request.RemoteIpAddress;

            // if unknown, assume not local
            if (String.IsNullOrEmpty(remoteAddress))
                return false;

            // check if localhost
            if (remoteAddress == "127.0.0.1" || remoteAddress == "::1")
                return true;

            // compare with local address
            if (remoteAddress == context.Request.LocalIpAddress)
                return true;

            return false;
        }
    }

可以看出來對remoteaddress做了限制。

 

如果不考慮安全的場合,可以采用以下做法:

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseHangfire(config =>
            {
                config.UseAuthorizationFilters(new DontUseThisAuthorizationFilter());

                config
                    .UseSqlServerStorage(@"server=xxxxx;database=Hangfire;uid=sa;pwd=123.com")
                    .UseMsmqQueues(@".\Private$\hangfire{0}", "default", "critical");
            });

             app.MapHangfireDashboard();
        }
    }

 

    public class DontUseThisAuthorizationFilter : IAuthorizationFilter
    {
        public bool Authorize(IDictionary<string, object> owinEnvironment)
        {
            return true;
        }
    }

 

 

 

如果需要結合現有系統權限機制的場合,也是實現IAuthorizationFilter:

 GlobalContext.Current.UserInfo是我們系統內部的一個上下文class。
    public class CustomAuthorizationFilter : IAuthorizationFilter
    {
        public bool Authorize(IDictionary<string, object> owinEnvironment)
        {
            var context = new OwinContext(owinEnvironment);
            if ( GlobalContext.Current.UserInfo==null){
                string urls = "/Index/Login?url=" + context.Request.Uri.Host;
                context.Response.Redirect(urls);
                return false;  
            }
            return true; 
        }
    }        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM