4

我有一个自定义的 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:注入用户 IPrincipal 的正确方法是什么?我将能够@User.Identity.FirstName在我的应用程序中访问。

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

4

2 回答 2

3

我建议创建您自己的基础 WebViewPage。请参阅http://haacked.com/archive/2011/02/21/changeing-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属性,因为即使在运行时它会变成 type FeedbkPrincipal,您的类也不知道这一点。依赖注入不是您当前问题的解决方案,因为您确实需要一种访问具体类的方法。

于 2012-05-09T00:07:27.687 回答
1

假设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
于 2012-05-09T00:26:31.653 回答