简体   繁体   English

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

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

I've got a custom IIdentity implementation: 我有一个自定义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); }
    }
}

and custom IPrincipal 和自定义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;
    }
}

In global.asax.cs I'm deserializing FormsAuthenticationTicket userData and replacing 在global.asax.cs中,我正在反序化FormsAuthenticationTicket userData并替换

HttpContext.Current.User: 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;
    }
}

Then, in Razor Views I can do: 然后,在Razor Views中我可以做到:

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

I'm already using Ninject to inject custom User Repository for the membership provider and I've been trying to bind IPrincipal to HttpContext.Current.User: 我已经在使用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();
    }
}

but it doesn't work. 但它不起作用。

All I'm trying to do is to be able to access my custom IIdentity properties like this: @User.Identity.FirstName 我所要做的就是能够访问我的自定义IIdentity属性,如下所示: @User.Identity.FirstName

How can I make this work? 我怎样才能做到这一点?

EDIT 编辑

I was expecting that by binding IPrincipal to HttpContext.Current.User as suggested here: MVC3 + Ninject: What is the proper way to inject the User IPrincipal? 我期待通过将IPrincipal绑定到HttpContext.Current.User,如下所示: MVC3 + Ninject:注入User IPrincipal的正确方法是什么? I will be able to access @User.Identity.FirstName in my application. 我将能够在我的应用程序中访问@User.Identity.FirstName

If this is not the case, what is the purpose of binding IPrincipal to HttpContext.Current.User as shown in the linked question? 如果不是这样,那么将IPrincipal绑定到HttpContext.Current.User的目的是什么,如链接问题所示?

I'd recommend creating your own base WebViewPage. 我建议您创建自己的基础WebViewPage。 See http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx

Then inside that you could do 然后在里面,你可以做到

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

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

Then it's just 那就是

@FeedbkIdentity.FirstName

within the view. 在视图内。

what is the purpose of binding IPrincipal to HttpContext.Current.User as shown in the linked question 将IPrincipal绑定到HttpContext.Current.User的目的是什么,如链接问题所示

Dependency injection lets you choose your components at run time. 依赖注入允许您在运行时选择组件。 In the example given, you could do 在给出的示例中,您可以这样做

public MyClassConstructor(IPrincipal principal) { // }

and IPrincipal would automatically be bound to the User. 和IPrincipal将自动绑定到用户。 Note this would not let you access your specific FeedbkPrincipal properties because even though at runtime it would become of type FeedbkPrincipal , your class doesn't know that. 请注意,这不会让您访问特定的FeedbkPrincipal属性,因为即使在运行时它将变为FeedbkPrincipal类型,您的类也不知道。 Dependency injection isn't a solution to your current issue because you do need a way of accessing your concrete classes. 依赖注入不是当前问题的解决方案,因为您确实需要一种访问具体类的方法。

Assuming that HttpContext.User gets set correctly, you could create a global filter to automatically populate your ViewBag with your FeedbkIdentity . 假设HttpContext.User得到正确设置,您可以创建一个全球性的过滤器来自动填充您的ViewBagFeedbkIdentity

Eg 例如

Create it 创造它

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

Register it 注册它

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

Use it 用它

@ViewBag.Identity.FirstName

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

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