繁体   English   中英

在ASP.NET MVC 3中注入IPrincipal - 我做错了什么?

[英]Injecting IPrincipal in ASP.NET MVC 3 - What am I doing wrong?

我有一个自定义IIdentity实现:

public class FeedbkIdentity : IIdentity
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string Name { get; set; }

    public FeedbkIdentity() 
    {
        // Empty contructor for deserialization
    }

    public FeedbkIdentity(string name)
    {
        this.Name = name;
    }

    public string AuthenticationType
    {
        get { return "Custom"; }
    }

    public bool IsAuthenticated
    {
        get { return !string.IsNullOrEmpty(this.Name); }
    }
}

和自定义IPrincipal

public class FeedbkPrincipal : IPrincipal
{
    public IIdentity Identity { get; private set; }

    public FeedbkPrincipal(FeedbkIdentity customIdentity)
    {
        this.Identity = customIdentity;
    }

    public bool IsInRole(string role)
    {
        return true;
    }
}

在global.asax.cs中,我正在反序化FormsAuthenticationTicket userData并替换

HttpContext.Current.User:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        FeedbkIdentity identity = serializer.Deserialize<FeedbkIdentity>(authTicket.UserData);

        FeedbkPrincipal newUser = new FeedbkPrincipal(identity);
        HttpContext.Current.User = newUser;
    }
}

然后,在Razor Views中我可以做到:

@(((User as FeedbkPrincipal).Identity as FeedbkIdentity).FirstName) 

我已经在使用Ninject为成员资格提供程序注入自定义用户存储库,我一直在尝试将IPrincipal绑定到HttpContext.Current.User:

internal class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IUserRepository>().To<EFUserRepository>();
        Bind<IPrincipal>().ToMethod(ctx => ctx.Kernel.Get<RequestContext>().HttpContext.User).InRequestScope();
    }
}

但它不起作用。

我所要做的就是能够访问我的自定义IIdentity属性,如下所示: @User.Identity.FirstName

我怎样才能做到这一点?

编辑

我期待通过将IPrincipal绑定到HttpContext.Current.User,如下所示: MVC3 + Ninject:注入User IPrincipal的正确方法是什么? 我将能够在我的应用程序中访问@User.Identity.FirstName

如果不是这样,那么将IPrincipal绑定到HttpContext.Current.User的目的是什么,如链接问题所示?

我建议您创建自己的基础WebViewPage。 http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx

然后在里面,你可以做到

public FeedbkPrincipal FeedbkPrincipal
{
    get
    {
        return User as FeedbkPrincipal;
    }
}

public FeedbkIdentity FeedbkIdentity
{
     get
     {
         return FeedbkPrincipal.Identity as FeedbkIdentity;
     }
}

那就是

@FeedbkIdentity.FirstName

在视图内。

将IPrincipal绑定到HttpContext.Current.User的目的是什么,如链接问题所示

依赖注入允许您在运行时选择组件。 在给出的示例中,您可以这样做

public MyClassConstructor(IPrincipal principal) { // }

和IPrincipal将自动绑定到用户。 请注意,这不会让您访问特定的FeedbkPrincipal属性,因为即使在运行时它将变为FeedbkPrincipal类型,您的类也不知道。 依赖注入不是当前问题的解决方案,因为您确实需要一种访问具体类的方法。

假设HttpContext.User得到正确设置,您可以创建一个全球性的过滤器来自动填充您的ViewBagFeedbkIdentity

例如

创造它

public class FeedbkPrincipalIntoViewBagAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var principal = filterContext.HttpContext.User as FeedbkPrincipal;
        if (principal != null)
        {
            filterContext.Controller.ViewBag.Identity = principal.Identity as FeedbkIdentity;
        }
    }
}

注册它

protected void Application_Start()
{
    GlobalFilters.Filters.Add(new FeedbkPrincipalIntoViewBagAttribute());
}

用它

@ViewBag.Identity.FirstName

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM