关于 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; 

        }

    }        

 

你可能感兴趣的:(权限)