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)
-
0
What environment do you deploy your application to? IIS?
-
0
// 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
-
0
Application deploy to IIS
-
0
@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.
-
0
Are we able to use IIS deploy, I couldn't understand the your answer :(
-
1
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.
-
0
@enerjisauretim
Or you can remove the permisson when enabling hagfire dashboard. But, in that case, everyone can see the hangfire dashboard.
-
1
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 topnew 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.
-
0
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.
-
0
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!
-
0
@ismcagdas and @sedulen thank you.