MVC 3、ニンジェクト 2.2。
バインディングを一時的にオーバーライドする必要があるシナリオがあります。オーバーライドは、コントローラー内のアクションの期間中だけです。
私が必要とするのは次のようなものです:
[HttpGet, Authorize(Users="MySpecialAccount")]
public ActionResult Report(string userName) {
var reportViewModel = new ReportViewModel();
using(var block = Kernel.BeginBlock() {
var principal = //load principal info based on userName;
block.Rebind<IMyPrincipal>().ToConstant(principal);
reportViewModel = GetViewModel(); //calls bunch of repos to hydrate view model that reference IMyPrincipal
}
return View(reportViewModel);
}
バックグラウンド:
アプリケーションは Windows 認証を使用します。カスタム プリンシパルをロードするカスタム プロバイダーがあります。このカスタム プリンシパルを repos/services/etc に挿入し、認証されたユーザーに基づいて適切なデータをロードできるようにします。それはすべて長い間うまく機能してきました。これで、1 つのアクションで偽装を使用するシナリオができました。その理由はおそらく範囲を超えていますが、基本的には、別のアカウントで HTML/Action をロードする別のプロセスを起動する HTMLToPDF ライターを使用しています。とにかく、私はこの1つのアクションで偽装しているため、リクエストを行ったのはユーザーではないため、すべてのリポジトリが正しい情報をロードできません。そのため、レポートを実行する必要がある「誰」のパラメーターを送信し、カスタム プリンシパルを一時的に再バインドする必要があります。
これが理にかなっていることを願っています。カスタム プリンシパルをロードする現在のコードのスニペットを次に示します。
In Global.asax:
protected void WindowsAuthentication_OnAuthenticate(Object source, WindowsAuthenticationEventArgs e)
{
if (e.Identity.IsAuthenticated)
{
//goes to db and loads additional info about logged on user. We use this info in repos/services to load correct data for logged on user.
var principal = new PrincipalFactory().GetPrincipal(e.Identity);
e.User = principal;
}
}
//Ninject Binding
Bind<IMyPrincipal>().ToProvider(new MyPrincipalProvider());
//Provider
public class MyPrincipalProvider : Provider<IMyPrincipal>
{
protected override IMyPrincipal CreateInstance(IContext context)
{
var principal = HttpContext.Current.User as IMyPrincipal;
return principal ?? new UnauthenticatedPrincipal(new GenericIdentity("Not Authenticated"));
}
}
ご協力いただきありがとうございます!