4

在我的 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;
}
4

1 回答 1

6

Principal 不是你可以在编写 auth cookie 时设置一次然后忘记的东西。在后续请求期间,将读取 auth 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(尽管我不确定它来自哪里或为什么需要它)。

于 2012-08-11T10:44:44.010 回答