无法访问Hangfire仪表板

时间:2019-07-23 14:03:22

标签: asp.net-core hangfire

当我尝试访问localhost:5000 / hangfire时,我被重定向到错误页面(我有一个返回相对状态页面的控制器(400,404等))

这是我遇到的错误:enter image description here

我想/ hangfire不存在。它所指的“ HandeErrorCode”来自我的控制器。

[Route ("Error/{statusCode}")]
        public IActionResult HandleErrorCode (int statusCode) {
            var statusCodeData = 
HttpContext.Features.Get<IStatusCodeReExecuteFeature> ();

        switch (statusCode) {
            case 404:
                return View("Status404");
            case 401:
                return View("Status401");
            case 400:
                return View("Status400");    
            case 500:
                return View("Status500");
        }

        return View ();
    }

Startup.cs

ConfigureServices

services.AddHangfire(configuration=>{
              configuration.UsePostgreSqlStorage(connectionString);
          }); 

配置

app.UseHangfireDashboard("/hangfire");    
      app.UseHangfireServer();

编辑: 整个Startup.cs

public class Startup {
public Startup (IHostingEnvironment env) {

  Console.WriteLine ("startin app {0}, which uses env {1} and has root {2}", env.ApplicationName, env.EnvironmentName, env.ContentRootPath);
  Configuration = new ConfigurationBuilder ()
    .SetBasePath (env.ContentRootPath)
    .AddJsonFile ("appsettings.json", optional : true, reloadOnChange : true)
    .AddJsonFile ($"appsettings.{env.EnvironmentName}.json", optional : true)
    .AddEnvironmentVariables ()
    .Build ();

  Console.WriteLine ("Current env variables are as follows: ");
  var enumerator = Environment.GetEnvironmentVariables ().GetEnumerator ();
  while (enumerator.MoveNext ()) {
    Console.WriteLine ($"{enumerator.Key,5}:{enumerator.Value,100}");
  }

}

public IConfigurationRoot Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices (IServiceCollection services) {

  services.AddMvc ();
  // Add framework services.
  var connectionString = Configuration["ConnectionStrings:DefaultConnection"];

  Console.WriteLine ("using conn str: {0}", connectionString);
  services.AddEntityFrameworkNpgsql ()
    .AddDbContext<EntityContext> (
      options => options.UseNpgsql (connectionString)

    );
  services.AddIdentity<User, Role> (config => {
      config.SignIn.RequireConfirmedEmail = true;
    })
    .AddEntityFrameworkStores<EntityContext> ()
    .AddDefaultTokenProviders ();

  services.Configure<IdentityOptions> (options => {
    options.Password.RequireDigit = false;
    options.Password.RequiredLength = 5;
    options.Password.RequireLowercase = false;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequireUppercase = false;
  });

  services.ConfigureApplicationCookie (options => options.LoginPath = "/account/login");

  services.AddAuthentication (CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie (options => {
      options.LoginPath = "/Account/Login";
      options.LogoutPath = "/Account/Logout";
    });

  // SERVICE FILTERS
  services.AddScoped<ActivePackageFilterAttribute, ActivePackageFilterAttribute> ();
  services.AddScoped<ActiveUserFilterAttribute, ActiveUserFilterAttribute> ();
  services.AddSingleton<AccountBilling, AccountBilling> ();

  services.AddMemoryCache ();

  services.AddHangfire (configuration => {
    configuration.UsePostgreSqlStorage (connectionString);
  });

  services.AddMvc (config => {
      config.ModelBinderProviders.Insert (0, new InvariantDecimalModelBinderProvider ());
      //config.Filters.Add(typeof(RedirectActionFilter));
    })
    .SetCompatibilityVersion (CompatibilityVersion.Version_2_2)
    .AddJsonOptions (options => {
      options.SerializerSettings.ContractResolver = new DefaultContractResolver ();
      options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    })
    .AddViewLocalization (LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
    .AddDataAnnotationsLocalization ();

  //services.AddScoped<RedirectActionFilter>();
  services.AddAutoMapper ();

  services.AddSingleton<AutoMapper.IConfigurationProvider> (Automapper.AutoMapperConfig.RegisterMappings ());

  //services.AddSingleton(Mapper.Configuration);
  services.AddScoped<IMapper> (sp => new Mapper (sp.GetRequiredService<AutoMapper.IConfigurationProvider> (), sp.GetService));

  services.AddDistributedMemoryCache (); // Adds a default in-memory implementation of IDistributedCache
  services.AddSession ();
  // Add application services.
  services.AddTransient<IEmailSender, AuthMessageSender> ();
  services.AddTransient<ISmsSender, AuthMessageSender> ();

  services.AddScoped<IRepository, Repository> ();
  services.AddScoped<Context, Context> ();

  services.AddScoped<IAccountBilling, AccountBilling> ();

  services.Configure<AdministratorEmailAddress> (Configuration);
  services.Configure<AuthMessageSenderOptions> (Configuration);
  services.Configure<TBCPaymentOptions> (Configuration);
  services.AddScoped<ViewRender, ViewRender> ();
  services.AddSingleton<IHttpContextAccessor, HttpContextAccessor> ();
  services.Configure<RequestLocalizationOptions> (opts => {
    var supportedCultures = new [] {
    new CultureInfo ("en"),
    new CultureInfo ("ka"),
    new CultureInfo ("ru")
    };

    opts.DefaultRequestCulture = new RequestCulture ("ka");
    // Formatting numbers, dates, etc.
    opts.SupportedCultures = supportedCultures;
    // UI strings that we have localized.
    opts.SupportedUICultures = supportedCultures;
  });

  // Add converter to DI
  //services.AddSingleton(typeof(IConverter), new BasicConverter(new PdfTools()));
  services.AddSingleton<ITemplateService, TemplateService> ();
  services.AddSingleton (typeof (IConverter), new SynchronizedConverter (new PdfTools ()));
  services.AddScoped<MailComposer> ();

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure (IApplicationBuilder app, IHostingEnvironment env) {

  if (env.IsDevelopment ()) {
    app.UseDeveloperExceptionPage ();
    app.UseDatabaseErrorPage ();
  } else {
    app.UseStatusCodePagesWithReExecute ("/Error/{0}");
  }

  app.UseStaticFiles ();

  app.UseAuthentication ();

  app.UseForwardedHeaders (new ForwardedHeadersOptions {
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
  });

  var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>> ();
  app.UseRequestLocalization (options.Value);

  app.UseSession ();

  // app.UseHangfireDashboard ("/hangfire", new DashboardOptions {
  //   Authorization = new [] { new HangFireAuthorization () }
  // });

  app.UseHangfireDashboard ();
  app.UseHangfireServer ();
  RecurringJob.AddOrUpdate<IAccountBilling> (a => a.CheckUserPayment (), Cron.Minutely);
  RecurringJob.AddOrUpdate<IAccountBilling> ("CalculateUserCharge", a => a.CalculateUserCharge (DateTime.Today.AddDays (-1)), Cron.Daily (21, 00), TimeZoneInfo.Utc);
  //RecurringJob.AddOrUpdate<IAccountBilling>("CalculateUserCharge",a=>a.CalculateUserCharge(DateTime.Today.AddDays(-1)),Cron.Minutely);

  app.UseMvc (routes => {
    routes.MapRoute (
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });
}

}     }

HangfireAuthorization.cs

public class HangFireAuthorization: IDashboardAuthorizationFilter{

public bool Authorize([NotNull] DashboardContext context)
{
    return context.GetHttpContext().User.IsInRole("Administrator");
}

}

如何访问hangfire仪表板?

2 个答案:

答案 0 :(得分:1)

对于Hangfire Dashboard,它公开了有关后台作业的敏感信息,包括方法名称和序列化参数,并为您提供了通过执行不同的操作(重试,删除,触发等)来管理它们的机会。限制对仪表板的访问非常重要。

为确保默认情况下的安全,仅允许本地请求,但是您可以通过传递自己的IDashboardAuthorizationFilter接口的实现来更改此设置,该接口的Authorize方法用于允许或禁止请求。第一步是提供您自己的实现。

引用Configuring Authorization

更新:

对此行为已在上面进行了描述,并由HangfireApplicationBuilderExtensions控制。它注册LocalRequestsOnlyAuthorizationFilter

如果要启用对非本地主机的请求,则需要提供DashboardOptions

答案 1 :(得分:0)

仔细检查此代码,以查看其配置是否正确

public void ConfigureServices(IServiceCollection services)
{
    // Add Hangfire services.
    services.AddHangfire(configuration => configuration
        .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
        .UseSimpleAssemblyNameTypeSerializer()
        .UseRecommendedSerializerSettings()
        .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
        {
            CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
            SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
            QueuePollInterval = TimeSpan.Zero,
            UseRecommendedIsolationLevel = true,
            UsePageLocksOnDequeue = true,
            DisableGlobalLocks = true
        }));

    // Add the processing server as IHostedService
    services.AddHangfireServer();

    // Add framework services.
    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IHostingEnvironment env)
{
    // ...
    app.UseStaticFiles();

    app.UseHangfireDashboard();
    backgroundJobs.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

您也不需要像这样的hangfire网址

app.UseHangfireDashboard("/hangfire");    

只需使用

app.UseHangfireDashboard();

因为文档已经说过here

  

启动应用程序后,打开以下URL(假设您的应用程序   在5000端口上运行)以访问Hangfire信息中心   接口。如我们所见,我们的后台工作已经完成   成功。

     

http://localhost:5000/hangfire