我有一个自定义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: What is the proper way to inject the User IPrincipal?我将能够在我的应用程序中访问@User.Identity.FirstName
。
如果不是这样,那么将IPrincipal绑定到HttpContext.Current.User的目的是什么,如链接问题所示?
答案 0 :(得分:3)
我建议您创建自己的基础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
,您的类也不知道。依赖注入不是当前问题的解决方案,因为您确实需要一种访问具体类的方法。
答案 1 :(得分:1)
假设HttpContext.User
设置正确,您可以创建一个全局过滤器,以使用ViewBag
自动填充FeedbkIdentity
。
E.g。
创建
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