asp.net-mvc - Ninject 上下文绑定(bind)的实际应用

标签 asp.net-mvc ninject

MVC 3、Ninject 2.2。

我有一个场景,我需要临时覆盖绑定(bind)。覆盖仅适用于 Controller 中操作的持续时间。

我需要的是这样的:

[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 身份验证。我有一个加载自定义主体的自定义提供程序。我们将此自定义主体注入(inject)到我们的存储库/服务/等中,并帮助我们根据经过身份验证的用户加载适当的数据。长期以来,这一切都非常有效。现在我有一个场景,我在一个操作中使用模拟。原因可能超出了范围,但基本上我使用的是 HTMLToPDF 编写器,它启动一个单独的进程来在不同的帐户下加载 HTML/Action。无论如何,因为我在这一操作中进行模拟,所以我的所有存储库都无法加载正确的信息,因为不是发出请求的用户,这是有道理的。因此,我发送了一个参数“谁”,我们需要为其运行报告,并且我需要暂时重新绑定(bind)自定义主体。

希望这是有道理的。以下是加载自定义主体的当前代码片段。

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

感谢您的帮助!

最佳答案

我想到的一种可能性是使用自定义授权属性:

public class ImpersonateAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        string username = httpContext.User.Identity.Name;

        // or if you wanted to load the username from the request:
        // string username = httpContext.Request["username"];

        IPrincipal principal = // load principal info based on username;

        // Swap the principal for this action
        httpContext.User = principal;

        return true;
    }
}

然后:

[HttpGet]
[ImpersonateAuthorize(Users="MySpecialAccount")]
public ActionResult Report(string userName) 
{
    // Here this.User will be the custom principal you loaded in 
    // the authorize attribute

    var reportViewModel = new ReportViewModel();

    return View(reportViewModel);
}

另一种方法是在 DI 框架配置级别执行此操作:

public class MyPrincipalProvider : Provider<IPrincipal>
{
    protected override IPrincipal CreateInstance(IContext context)
    {
        var httpContext = HttpContext.Current;
        var rd = httpContext.Request.RequestContext.RouteData;
        var currentAction = rd.GetRequiredString("action");
        var currentController = rd.GetRequiredString("controller");
        if (string.Equals("report", currentAction, StringComparison.OrdinalIgnoreCase) &&
            string.Equals("users", currentController, StringComparison.OrdinalIgnoreCase))
        {
            IPrincipal principal = // load principal info based on username;
            return principal;
        }

        var principal = httpContext.User as IPrincipal;
        return principal ?? new UnauthenticatedPrincipal(new GenericIdentity("Not Authenticated"));
    }
}

关于asp.net-mvc - Ninject 上下文绑定(bind)的实际应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12100556/

相关文章:

asp.net-mvc - mvc基于同一页面上用户输入的动态局部 View

javascript - 在 Asp.net MVC 母版页中设置 Body 的 OnLoad 属性

architecture - 最具争议的帖子,IoC,Ninject,只是让东西工作

c# - MVC/n注入(inject) : Implementing My Own ApplicationUserManager

c# - SignalR 1.0 - 向特定客户端发送数据

asp.net-mvc - TempData keep() 与 peek()

asp.net-mvc - ASP.NET MVC 5-(HTTP错误404.0-找不到)带有长的不存在的URL

c# - Ninject:WithConstructorArgument 和 WithPropertyValue 不起作用

asp.net-mvc-3 - MVC Controller - 在 Controller 中注入(inject) 2 个存储库

asp.net - 使用 Asp.Net MVC 和 Web Api 配置 Ninject