MVC Webアプリ内でHangFireを実行していますが、 http:// MyApp/hangfire に移動しようとすると、ログインしていないかのようにアプリのログインページにリダイレクトされます。
承認の要件を明示的に構成していません...私はweb.configに以下を含めましたが、これを機能させるためにそれを取り出しました。
<location path="hangfire">
<system.web>
<authorization>
<allow roles="Administrator" />
<deny users="*" />
</authorization>
</system.web>
理論的には、これが私が望むものであり、メインのWebアプリケーションにログインすると、Administrator
ロールでログインするため、このルールが機能するはずです。
しかし、それをweb.configで構成しているかどうかに関係なく、 http:// MyApp/hangfire に移動しようとすると、web.configで構成されているアプリのログインページにリダイレクトされます:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="960" />
</authentication>
ホストに公開したときだけ、ローカルマシンではこれを行いません。 HangFireは、ログイン時にメインアプリが提供する認証Cookieを認識しませんか?一般的に、hangfireアプリは認証を必要としないので、他の構成では認証が必要だと考えているのでしょうか。
更新1:
hangfire docs に従って認証フィルターを追加しましたが、同じことが起こります。これがStartup.csの私のコードです。
using Hangfire;
using Hangfire.Logging;
using Hangfire.Dashboard;
using Hangfire.SqlServer;
using Microsoft.Owin;
using OTIS.Web.AppCode;
using OTISScheduler.AppServ;
using Owin;
using System.Web.Security;
[Assembly: OwinStartup(typeof(OTIS.Web.App_Start.Startup))]
namespace OTIS.Web.App_Start
{
public class Startup
{
public void Configuration(IAppBuilder app) {
app.UseHangfire(config => {
config.UseSqlServerStorage("DefaultConnection");
config.UseServer();
//Dashboard authorization
config.UseAuthorizationFilters(new AuthorizationFilter
{
Users = "USERA", // allow only specified users (comma delimited list)
Roles = "Account Administrator, Administrator" // allow only specified roles(comma delimited list)
});
});
LogProvider.SetCurrentLogProvider(new StubLogProviderForHangfire());
GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });
var scheduleTasksInitializer = new ScheduleTasksInitializer();
scheduleTasksInitializer.ScheduleTasks();
}
}
}
更新2:
もっと 基本認証を示す詳細な説明 に従って、私もこれを試してみました...それでもまだ運がありません。アプリのログインページにリダイレクトされます。
config.UseAuthorizationFilters(
new BasicAuthAuthorizationFilter(
new BasicAuthAuthorizationFilterOptions
{
// Require secure connection for dashboard
RequireSsl = false,
SslRedirect = false,
// Case sensitive login checking
LoginCaseSensitive = true,
// Users
Users = new[]
{
new BasicAuthAuthorizationUser
{
Login = "MyLogin",
// Password as plain text
PasswordClear = "MyPwd"
}
}
}));
ようやく動作しました。独自のAuthorizationFilterクラスを作成しました(以下を参照)。次に、それをStartup.cs構成メソッドのMapHangfireDashboardメソッドに渡しました(以下を参照)。
public class HangFireAuthorizationFilter : IAuthorizationFilter
{
public bool Authorize(IDictionary<string, object> owinEnvironment)
{
bool boolAuthorizeCurrentUserToAccessHangFireDashboard = false;
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if(HttpContext.Current.User.IsInRole("Account Administrator"))
boolAuthorizeCurrentUserToAccessHangFireDashboard = true;
}
return boolAuthorizeCurrentUserToAccessHangFireDashboard;
}
}
HangfireをカスタムURLにマップし、使用するAuthorizationFilterを指定するには:
public void Configuration(IAppBuilder app) {
//Get from web.config to determine to fire up hangfire scheduler or not
app.UseHangfire(config => {
config.UseSqlServerStorage("DefaultConnection");
config.UseServer();
});
//map hangfire to a url and specify the authorization filter to use to allow access
app.MapHangfireDashboard("/Admin/jobs", new[] { new HangFireAuthorizationFilter() });
}
新しいバージョンでは、IDashboardAuthorizationFilter
を使用する必要があります。 usingステートメントを使用すると、次のようになります。
using System.Web;
using Hangfire.Annotations;
using Hangfire.Dashboard;
namespace Scheduler.Hangfire
{
public class HangFireAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
//can add some more logic here...
return HttpContext.Current.User.Identity.IsAuthenticated;
}
}
}
次に構成セクションで:
app.UseHangfireDashboard("/jobs", new DashboardOptions()
{
Authorization = new [] {new HangFireAuthorizationFilter()}
});
設計どおり、私は信じています。
ダッシュボードのドキュメント を参照してください。
デフォルトでは、Hangfireはローカルリクエストに対してのみダッシュボードページへのアクセスを許可します。
奇妙なことに、先日これに対処していましたが、 Autofac 依存性注入を使用している場合は、アイテムを正しい順序で構成する必要があることを認識しておく必要があります。具体的には、Hangfireafter他の認証だけでなく、私の場合は MembershipRebootbefore他のOAuthもの。
かなりの試行錯誤を繰り返しました。