在我的ASP.NET MVC应用程序中,我正在尝试创建一个自定义的HttpContent.User对象。我首先创建了一个实现IPrincioal的Member类。
public class Member : IPrincipal
{
public string Id { get; set; }
public IIdentity Identity { get; set; }
public bool IsInRole(string role) { throw new NotImplementedException(); }
...
}
然后在身份验证时,我将HttpContext.User设置为Member类的实例:
FormsAuthentication.SetAuthCookie(email, false);
HttpContext.User = member;
然后我想检查用户是否经过身份验证,如下所示:
if (User.Identity.IsAuthenticated) { ... }
那就是我被困住的地方。 我不确定我需要为成员实例上的public IIdentity Identity
属性做些什么。这样我就可以使用像这样的HttpContext.User对象:
IsAuthenticated = HttpContext.User.Identity.IsAuthenticated;
ViewBag.IsAuthenticated = IsAuthenticated;
if (IsAuthenticated) {
CurrentMember = (Member)HttpContext.User;
ViewBag.CurrentMember = CurrentMember;
}
答案 0 :(得分:6)
在编写auth cookie时,Principal不是你可以设置的东西而是稍后忘记。在后续请求期间,将读取身份验证cookie,并在执行操作方法之前重建IPrincipal
/ IIdentity
。发生这种情况时,尝试将HttpContext.User
强制转换为自定义Member
类型会引发异常。
一种选择是拦截ActionFilter
,然后包装标准实现。
public class UsesCustomPrincipalAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var systemPrincipal = filterContext.HttpContext.User;
var customPrincipal = new Member(systemPrincipal)
{
Id = "not sure where this comes from",
};
filterContext.HttpContext.User = customPrincipal;
}
}
public class Member : IPrincipal
{
private readonly IPrincipal _systemPrincipal;
public Member(IPrincipal principal)
{
if (principal == null) throw new ArgumentNullException("principal");
_systemPrincipal = principal;
}
public string Id { get; set; }
public IIdentity Identity { get { return _systemPrincipal.Identity; } }
public bool IsInRole(string role)
{
return _systemPrincipal.IsInRole(role);
}
}
通过这种方式,您不会丢失任何带有默认IPrincipal
和IIdentity
实现的开箱即用的内容。您仍然可以IsAuthenticated
上的IIdentity
,甚至IsInRole(string)
上的IPrincipal
调用Id
。您唯一获得的是自定义IPrincipal
实施中的额外{{1}}属性(虽然我不确定它来自何处或您需要它的原因)。