Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC中带有表单身份验证的自定义IPrincipal_C#_Asp.net Mvc_Authorization_Iprincipal - Fatal编程技术网

C# ASP.NET MVC中带有表单身份验证的自定义IPrincipal

C# ASP.NET MVC中带有表单身份验证的自定义IPrincipal,c#,asp.net-mvc,authorization,iprincipal,C#,Asp.net Mvc,Authorization,Iprincipal,这应该很简单,但我在谷歌上搜索了这么多之后,还是无法理解。这是我想要的。我有一个自定义用户表(目前没有角色),我想对其进行授权。为此,我必须实现一个自定义成员资格提供程序,我已经完成了。但我的问题是,如何将自定义IPrincipal设置为HttpContext.Current.User?这应该发生在哪里?假设我有以下设置: public class CustomMembershipProvider : MembershipProvider { private IUserRepository

这应该很简单,但我在谷歌上搜索了这么多之后,还是无法理解。这是我想要的。我有一个自定义用户表(目前没有角色),我想对其进行授权。为此,我必须实现一个自定义成员资格提供程序,我已经完成了。但我的问题是,如何将自定义IPrincipal设置为HttpContext.Current.User?这应该发生在哪里?假设我有以下设置:

public class CustomMembershipProvider : MembershipProvider
{
   private IUserRepository _repository;

   public CustomMembershipProvider(IUserRepository repository)
   {
      _repository = repository;
   }

   public override bool ValidateUser(string username, string password)
   {
      //check user repository 
   }

   //additional methods omitted for brevity 
}
然后我有一个自定义用户类,实现了
IPrincipal
IIdentity

 public class CustomUser : IPrincipal
    {
        public CustomUser(string name, int userId, string additionalInfo)
        {
            Identity = new CustomIdentity(name, userId, additionalInfo);
        }

        public IIdentity Identity { get; private set; }

        public bool IsInRole(string role)
        {
            return true;
        }
    }

    public class CustomIdentity : IIdentity
    {
        public CustomIdentity(string name, int userId, string additionalInfo)
        {
            Name = name;
            UserId = userId;
            AdditionalInfo = additionalInfo;
        }

        public string Name { get; private set; }

        public string AuthenticationType
        {
            get { return "CustomAuth"; }
        }

        public bool IsAuthenticated
        {
            get { return !String.IsNullOrEmpty(Name); }
        }

        public int UserId { get; private set; }
        public string AdditionalInfo { get; private set; }
    }

所以我的问题是,将Context.User设置为此自定义用户的实例的正确位置在哪里?我需要自定义授权属性吗?如果是这样,那会是什么样子?

我建议为所有控制器使用自定义控制器基类

然后,在授权中调用

protected override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
{
    // Actual Authentication
    HttpContext.User = user; 
    Thread.CurrentPrincipal = user;
    base.OnAuthorization(filterContext);
}
我不完全确定如何调用成员资格提供程序,因为我正在手动执行它,但我认为您可以静态访问
membership.provider
,以执行实际的对象构造

我需要自定义授权属性吗


否。请注意身份验证和授权的区别:身份验证在您的系统中建立用户的身份。授权允许或拒绝特定请求。因此,
AuthorizeAttribute
还有一个
Roles
参数,允许仅由某些用户调用某个操作。

我不确定是否理解您的答案。当你说实际的身份验证时,你是在说在那里设置AuthCookie吗?那么,Loing表单本身在post上会做什么呢?按照我对会员资格提供商ValidateUser的理解,不应该经常调用ValidateUser——只要用户登录,他就会收到一个认证cookie,以后将使用它。但是,要获取用户对象,您必须访问数据库(或某些缓存)。但这是代码的一个要求。我认为MembershipProvider的设计不是很好,手动操作有很多好处。现在,在我写我的评论时,你更改了你的评论:)
OnAuthorization
将为每个请求调用,即使用户已经(表单-)验证;你点击数据库只是为了获取用户对象。很抱歉:)在每个请求上点击数据库听起来不太理想。但除此之外,我还不清楚//实际的身份验证部分应该是什么样子。在我的登录表单中,我会调用MembershipProvider.Validate()(或者您建议的自定义内容),但是对于OnAuthorization中的每个请求,应该发生什么呢?
OnAuthorization
只是从数据库中获取用户对象,这样您就可以设置用户了。无论如何,在每个请求中都可能需要用户——例如,确保此时允许用户执行该特定请求。当然,缓存是个好主意。然后您就可以随时安全地访问HttpContext.User。实际的身份验证(我没有写这篇文章)是在提交表单并调用
FormsAuthentication.SetAuthCookie
时发生的。您最终是如何处理的?我自己也在做类似的事情的早期。我也在同一条船上,我几乎准备好创建一个扩展方法来完成这项工作!