2017-01-12 3 views
1

ASP.NET Core MVC 응용 프로그램에서 Hangfire를 사용할 수있게되었습니다. 이제 관리자 권한을 추가하려고합니다.ASP.NET Core MVC Hangfire 사용자 지정 인증

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

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

가 지금은 사용자 정의 인증 필터에 문제가 :

은 내가 Startup.cs 파일에 다음 코드를 추가

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

이 IAutohorizationFilter와 이전 구성을위한 샘플이며, 양식 버전 1.6.8 거기에 새로운 인터페이스 IDashboardAuthorizationFilter, 그리고 그것을 구현하는 방법을 알아낼 수 없습니다.

내 웹 응용 프로그램에서 클레임을 사용합니다.

thnx

+0

당신이 hangfire의 버전을 사용합니까을 사용하여이 방법을 추가 할 필요가? –

답변

0

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

Kim Hoang,이 말을 해보면 다음과 같습니다. 예외 발생 : Hangfire.Core.dll의 'System.ArgumentException' 추가 정보 : 컨텍스트 인수의 형식은 OwinDashboardContext입니다. – Wasyster

+0

@Wasyster, 이상한데 실제로 MVC 5 용으로 구현 한 속성입니다. 그러나 MVC 코어에서도 동일하게 작동합니다. –

+0

런타임에서 여전히 throw 및 오류가 발생합니다. – Wasyster

1

여기에 .NET 코어 내 구현의 나는 당신의 시작에서 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; 
    } 
} 

을 구현하는 방법은 다음과 같습니다

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(); 
    } 
} 

StartupConfigure에 그것을 설정 :

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"); 
    }); 
}; 
+0

이것은 작동하지 않습니다 –

+0

@FarajFarook 당신이 정교하게 만들 수있는 기회가 있습니까? .NET Core 1.0.1에서이 작업을 수행했습니다. 1.1에서 변경된 사항이 있습니다. – Ryan

+0

젠장. 내 잘못이야. Microsoft.Extensions.DependencyInjection을 사용하는 것을 잊어 버렸습니다. 전체 솔루션을 확인하고 제대로 작동하는지 확인해 보겠습니다.끝까지 혼란스럽게해서 죄송합니다. –

0

것은 당신이 .NET 코어 2.0을 사용하는 경우, 당신은 새로운 인증 기준을 준수하기 위해 사용자 정의 구현을해야합니다.

미들웨어를 추가해야합니다. 이것은 Github 페이지/문제에서 HangFire가 제공 한 것입니다. 당신의 Startup.cs 에서 다음

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); 
    } 
} 

당신은

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); 
    }