Пользовательская проверка подлинности ASP.NET Core MVC Hangfire

Мне удалось работать с Hangfire в моем приложении ASP.NET Core MVC, и теперь я пытаюсь добавить авторизацию администратора.

Я добавил следующий код в файл Startup.cs:

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

app.UseHangfireServer();
RecurringJob.AddOrUpdate( () => Debug.WriteLine("Minutely Job"), Cron.Minutely);

Теперь у меня проблема с пользовательским фильтром авторизации:

public class HangFireAuthorizationFilter : IDashboardAuthorizationFilter
{
    public bool Authorize(DashboardContext context)
    {
        return true;
    }
}

Есть образцы для старой конфигурации с IAutohorizationFilter, а для версии 1.6.8 есть новый интерфейс IDashboardAuthorizationFilter, и я не могу понять, как его реализовать.

В моем веб-приложении используются утверждения.

спасибо


person Wasyster    schedule 12.01.2017    source источник
comment
Какую версию Hangfire вы используете?   -  person GôTô    schedule 13.01.2017


Ответы (4)


Вот моя реализация для .NET Core:

public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter {
    private string policyName;

    public HangfireAuthorizationFilter(string policyName) {
        this.policyName = policyName;
    }

    public bool Authorize([NotNull] DashboardContext context) {
        var httpContext = context.GetHttpContext();
        var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
        return authService.AuthorizeAsync(httpContext.User, this.policyName).ConfigureAwait(false).GetAwaiter().GetResult().Succeeded;
    }
}

Настройте его в Startup Configure с помощью:

app.UseHangfireDashboard(
            pathMatch: "/hangfire",
            options: new DashboardOptions() {
                Authorization = new IDashboardAuthorizationFilter[] {
                    new HangfireAuthorizationFilter("somePolicy")
                }
            });

Убедитесь, что выбранная вами политика (например, somePolicy) настроена ранее в Startup ConfigureServices. Например:

services.Configure<AuthorizationOptions>(options => {
    options.AddPolicy("somePolicy", policy => {
        // require the user to be authenticated
        policy.RequireAuthenticatedUser();
        // Maybe require a claim here, if you need that.
        //policy.RequireClaim(ClaimTypes.Role, "some role claim");
    });
});
person Ryan    schedule 09.03.2017
comment
@FarajFarook Есть ли шанс, что вы могли бы уточнить? У меня это работает на .NET Core 1.0.1, есть вероятность, что что-то изменилось в 1.1. - person Ryan; 07.06.2017
comment
Дерьмо человек. Виноват. Я забыл using Microsoft.Extensions.DependencyInjection;, я проверю все решение и поставлю вам лайк, если оно сработает. Прошу прощения за путаницу с моей стороны. - person Faraj Farook; 07.06.2017
comment
По какой-то причине мой контекст панели мониторинга не аутентифицирован. Я использую UserManager для входа через AccountController. - person Faraj Farook; 07.06.2017
comment
Я, вероятно, должен был быть более ясным в своем ответе, но убедились ли вы, что политика, которую вы вводите в HangfireAuthorizationFilter (в этом примере somePolicy), является действительной политикой, которую вы настроили? Я обновлю свой ответ. - person Ryan; 08.06.2017
comment
Достаточно хорошо работал с примером авторизации роли github.com/blowdart/AspNetAuthorizationWorkshop. - person Ricardo; 04.10.2018

Чтобы добавить настраиваемую базовую аутентификацию в Hangfire для ядра asp.net

Используйте пакет nuget Hangfire.Dashboard.Basic.Authentication.

Установить с помощью команды

Install-Package Hangfire.Dashboard.Basic.Authentication

Справочник

В методе настройки запуска добавьте следующее

app.UseHangfireDashboard("/hangfire", new DashboardOptions
        {
            //AppPath = "" //The path for the Back To Site link. Set to null in order to hide the Back To  Site link.
            DashboardTitle = "My Website",
            Authorization = new[]
        {
                new HangfireCustomBasicAuthenticationFilter{
                    User = _configuration.GetSection("HangfireSettings:UserName").Value,
                    Pass = _configuration.GetSection("HangfireSettings:Password").Value
                }
            }
        });

Добавьте следующее в appsettings.json (используйте свое имя пользователя и пароль)

 "HangfireSettings": {
     "UserName": "admin",
     "Password": "password"
 }
person Bibin Gangadharan    schedule 19.04.2020
comment
Спасибо за самый простой. - person Arsman Ahmad; 26.02.2021
comment
Это должен быть принятый ответ, работает с .net core 3.1, хранилищем sqlite и хранилищем памяти. - person SolidSnake; 27.07.2021

Если вы используете .NET Core 2.0, вам потребуется специальная реализация для соответствия новым стандартам проверки подлинности.

Вам нужно добавить промежуточное ПО. Это предоставлено HangFire на их странице Github/issues.

public class HangfireDashboardMiddleware
{
    private readonly DashboardOptions _dashboardOptions;
    private readonly JobStorage _jobStorage;
    private readonly RequestDelegate _nextRequestDelegate;
    private readonly RouteCollection _routeCollection;

    public HangfireDashboardMiddleware(
        RequestDelegate nextRequestDelegate,
        JobStorage storage,
        DashboardOptions options,
        RouteCollection routes)
    {
        _nextRequestDelegate = nextRequestDelegate;
        _jobStorage = storage;
        _dashboardOptions = options;
        _routeCollection = routes;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        var aspNetCoreDashboardContext =
            new AspNetCoreDashboardContext(_jobStorage, _dashboardOptions, httpContext);

        var findResult = _routeCollection.FindDispatcher(httpContext.Request.Path.Value);
        if (findResult == null)
        {
            await _nextRequestDelegate.Invoke(httpContext);
            return;
        }

        // attempt to authenticate against default auth scheme (this will attempt to authenticate using data in request, but doesn't send challenge)
        var result = await httpContext.AuthenticateAsync();

        if (!httpContext.User.Identity.IsAuthenticated)
        {
            // request was not authenticated, send challenge and do not continue processing this request
            await httpContext.ChallengeAsync();
        }

        if (_dashboardOptions
            .Authorization
            .Any(filter =>
                     filter.Authorize(aspNetCoreDashboardContext) == false))
        {
            var isAuthenticated = httpContext.User?.Identity?.IsAuthenticated;
            httpContext.Response.StatusCode = isAuthenticated == true
                                                  ? (int) HttpStatusCode.Forbidden
                                                  : (int) HttpStatusCode.Unauthorized;
            return;
        }

        aspNetCoreDashboardContext.UriMatch = findResult.Item2;
        await findResult.Item1.Dispatch(aspNetCoreDashboardContext);
    }
}

Затем в вашем Startup.cs вам нужно добавить этот метод

private static IApplicationBuilder UseHangfireDashboardCustom(IApplicationBuilder app,string pathMatch = "/hangfire",DashboardOptions options = null,JobStorage storage = null)
{
    var services = app.ApplicationServices;
    storage = storage ?? services.GetRequiredService<JobStorage>();
    options = options ?? services.GetService<DashboardOptions>() ?? new DashboardOptions();
    var routes = app.ApplicationServices.GetRequiredService<RouteCollection>();

    app.Map(new PathString(pathMatch), x =>
        x.UseMiddleware<HangfireDashboardMiddleware>(storage, options, routes));

    return app;
}

Наконец, используйте пользовательскую авторизацию

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseAuthentication();

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

        app.UseHangfireServer();

        //Voila!
        UseHangfireDashboardCustom(app);
    }
person Community    schedule 25.11.2017

Вот как я реализую IDashboardAuthorizationFilter

public class HangfireAuthorizeFilter : IDashboardAuthorizationFilter
{
    public bool Authorize(DashboardContext context)
    {
        var owinEnvironment = context.GetOwinEnvironment();
        if (owinEnvironment.ContainsKey("server.User"))
        {
            if (owinEnvironment["server.User"] is ClaimsPrincipal)
            {
                return (owinEnvironment["server.User"] as ClaimsPrincipal).Identity.IsAuthenticated;
            }
            else if (owinEnvironment["server.User"] is GenericPrincipal)
            {
                return (owinEnvironment["server.User"] as GenericPrincipal).Identity.IsAuthenticated;
            }
        }
        return false;
    }
}

В вашем стартапе

app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
    Authorization = new [] { new HangfireAuthorizeFilter() }
});
person Kim Hoang    schedule 13.01.2017
comment
Ким Хоанг, когда я пробую это, он говорит, что выдано исключение: «System.ArgumentException» в Hangfire.Core.dll. Дополнительная информация: Аргумент контекста должен быть типа OwinDashboardContext! - person Wasyster; 13.01.2017
comment
@Wasyster, это странно, на самом деле этот атрибут я реализую для MVC 5. Но он должен работать так же с ядром MVC. - person Kim Hoang; 14.01.2017