Base solution for your next web application
Open Closed

Hangfire Dashboard (Angular, Single solution) #6516


User avatar
0
enerjisauretim created

Hello,

We are using Aspnet Zero .Net Core + Angular Project. We can use Hangfire implementation and dashboard the local but when we deployed project cannot navigate to the Hangfire dashboard.

It says that site cannot be reached

We did Hangfire configuration on project Startup.cs

app.UseHangfireServer(); app.UseHangfireDashboard();

How can I solve?

Thank you


11 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    What environment do you deploy your application to? IIS?

  • User Avatar
    0
    ajayak created
    // Hangfire dashboard & server (Enable to use Hangfire instead of default job manager)
    var dashboardOptions = new DashboardOptions
    {
        Authorization = new[] { new AbpHangfireAuthorizationFilter(AppPermissions.Pages_Administration_HangfireDashboard) }
    };
    app.UseHangfireDashboard("/hangfire", DebugHelper.IsDebug ? null : dashboardOptions);
    app.UseHangfireServer();
    

    It will be a good idea to secure thr hangfire url for production

  • User Avatar
    0
    enerjisauretim created

    Application deploy to IIS

  • User Avatar
    0
    maliming created
    Support Team

    @enerjisauretim

    Out of IIS dependencies, Directly executed in the directory after the program is published:

    dotnet YourApplication.dll

    Then take a look at whether the Hangfire Dashboard is working properly.

  • User Avatar
    0
    enerjisauretim created

    Are we able to use IIS deploy, I couldn't understand the your answer :(

  • User Avatar
    1
    ismcagdas created
    Support Team

    Hi @enerjisauretim

    In ASP.NET Core & Angular version, you can't use HangFire dashboard since HangFire dashboard doesn't support token based authentication.

    So, if you want to use Hangfire Dashboard, you need to use ASP.NET Core & Jquery version.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @enerjisauretim

    Or you can remove the permisson when enabling hagfire dashboard. But, in that case, everyone can see the hangfire dashboard.

  • User Avatar
    1
    sedulen created

    I've seen this discussed a few times, and the best solution I've seen has been to implement a new Hangfire Dashboard Authorization Filter:

    1.) in Startup.cs, change the Hangfire Dashboard Authorization option to the following:

    options.Authorization = new[] { new HangfireTokenAuthorizationFilter(AppPermissions.Pages_Administration_HangfireDashboard) };
    

    2.) somewhere in your solution, mine is in my .Web.Host project, I have defined this class:

    public class HangfireTokenAuthorizationFilter : IDashboardAuthorizationFilter
    {
      private readonly string _requiredPermissionName;
    
      public HangfireTokenAuthorizationFilter(string requiredPermissionName = null)
      {
        _requiredPermissionName = requiredPermissionName;
      }
    
      public bool Authorize([NotNull]DashboardContext context)
      {
        var logger = context.GetHttpContext().RequestServices.GetRequiredService<ILogger>();
    
        // if we have a cookies and we are in release mode
        var cookies = context.GetHttpContext().Request.Cookies;
        if (cookies["Abp.AuthToken"] != null)
        {
          var jwtCookie = cookies["Abp.AuthToken"];
          string jwtToken = jwtCookie;
          JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
          JwtSecurityToken securityToken = handler.ReadToken(jwtToken) as JwtSecurityToken;
          var id = securityToken.Claims.FirstOrDefault(claim => claim.Type.EndsWith("sub"));
          var tenanIdClaim = securityToken.Claims.FirstOrDefault(claim => claim.Type.EndsWith("tenantId"));
          int? tenanId = null;
          if (tenanIdClaim != null)
          {
            tenanId = int.Parse(tenanIdClaim.Value);
          }
          logger.InfoFormat("[HangfireTokenAuthorizationFilter.Authorize]: checking Permissions: permission: '{0}', tenant: '{1}', user_id: '{2}'", _requiredPermissionName, tenanId, id.Value);
          var isPermissionGranted = IsPermissionGranted(context, _requiredPermissionName, new UserIdentifier(tenanId, long.Parse(id.Value)));
          if(!isPermissionGranted)
          {
            logger.WarnFormat("[HangfireTokenAuthorizationFilter.Authorize]: Unauthorized Attempt to access the Hangfire Dashboard: tenant: '{0}', user_id: '{1}'", _requiredPermissionName, tenanId, id.Value);
          }
          return isPermissionGranted;
        }
        logger.Warn("[HangfireTokenAuthorizationFilter.Authorize]: no Abp.AuthToken cookie present.");
        return false;
    
      }
    
      private static bool IsPermissionGranted(DashboardContext context, string requiredPermissionName, UserIdentifier userIdentifier)
      {
        var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IPermissionChecker>();
        return permissionChecker.IsGranted(userIdentifier, requiredPermissionName);
      }
    }
    

    3.) in your .Core project, under Authorization, in the AppPermissions.cs and AppAuthorizationProvider.cs classes, make sure that you have lines that define the Hangfire Dashboard permission

    administration.CreateChildPermission(AppPermissions.Pages_Administration_HangfireDashboard, L("HangfireDashboard"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);
    

    and

    public const string Pages_Administration_HangfireDashboard = "Pages.Administration.HangfireDashboard";
    

    At this point, when you setup role permissions through the .Web.Host UI, you should see Hangfire Dashboard listed as a permission-controlled item.

    Then the last step is you need to add navigation to the Hangfire Dashboard to your Admin UI.

    4.) In the .Web.Host project, under src\app\shared\layout\nav\app-navigation.service.ts, you need to add:

    import { AppConsts } from '@shared/AppConsts'; ~line 5 in the import statements @ the top

    new AppMenuItem('HangfireDashboard', 'Pages.Administration.HangfireDashboard', 'flaticon-line-graph', AppConsts.remoteServiceBaseUrl + '/hangfire', [], true), somewhere under your Administration AppMenuItem definition.

    once you have that you should now see Hangfire Dashboard in your Administration menu, and if you click on it, it should open a new tab/window to the Hangfire Dashboard using the correct authorization filter/scheme that adheres to your ASPNZ permissions model.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @sedulen

    This works for One solution downloads (merged Angular & ASP.NET Core solution). If you want to host Angular and server side app separately, it will not work.

    We couldn't find a good way to solve this problem until now.

  • User Avatar
    0
    sedulen created

    Understood. Thanks for the clarification @ismcagdas.

    I've only ever worked with the merged solution, so I haven't had to deal with hosting Angular & WebAPI separately.

    Cheers!

  • User Avatar
    0
    enerjisauretim created

    @ismcagdas and @sedulen thank you.