【问题标题】:How can I implement/Create role based custom user authentication in asp.net MVC 3如何在 asp.net MVC 3 中实现/创建基于角色的自定义用户身份验证
【发布时间】:2011-11-09 23:58:47
【问题描述】:

如何在 asp.net MVC 3 中实现基于角色的自定义用户身份验证。考虑我有两个表 UserInfo(UserId, UserName, Password,RoleId)Role(RoleId, RoleName)

我想从数据库(UserInfo 表)中验证用户,并且还想从该表中检索角色。并想使用like [Authorize(Roles="Admin")]

需要你的帮助和想法......

【问题讨论】:

    标签: asp.net-mvc-3 roles authentication


    【解决方案1】:

    您可以使用自定义授权属性并将角色存储在身份验证 cookie 的用户数据部分。因此,例如在您的 LogOn 方法中,一旦您验证了凭据,您就可以从数据库中检索给定用户的角色并将它们存储到用户数据中:

    // TODO: fetch roles from your database based on the username
    var roles = "Admin|SomeRole";
    var ticket = new FormsAuthenticationTicket(
        1, 
        username,
        DateTime.Now, 
        DateTime.Now.AddMilliseconds(FormsAuthentication.Timeout.TotalMilliseconds), 
        false, 
        roles
    );
    var encryptedTicket = FormsAuthentication.Encrypt(ticket);
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
    {
        Domain = FormsAuthentication.CookieDomain,
        HttpOnly = true,
        Secure = FormsAuthentication.RequireSSL,
    };
    
    // Emit the authentication cookie which in addition to the username will
    // contain the roles in the user data part
    Response.AppendCookie(authCookie);
    

    然后您可以编写一个自定义的授权属性,该属性将用于读取身份验证 cookie 并提取角色信息:

    public class MyAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext.User.Identity.IsAuthenticated)
            {
                var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (authCookie != null)
                {
                    var ticket = FormsAuthentication.Decrypt(authCookie.Value);
                    var identity = new GenericIdentity(httpContext.User.Identity.Name);
                    var roles = (ticket.UserData ?? string.Empty).Split('|');
                    httpContext.User = new GenericPrincipal(identity, roles);
                }
            }
    
            return base.AuthorizeCore(httpContext);
        }
    }
    

    现在剩下的就是用这个新属性来装饰你的控制器/动作:

    [MyAuthorize(Roles = "Admin")]
    public ActionResult Foo()
    {
        ...
    }
    

    更新:

    根据 cmets 部分的要求,您可以在自定义授权属性中覆盖 HandleUnauthorizedRequest 方法,以便如果用户无权访问给定操作,他将被重定向到某个错误视图而不是登录页面:

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new ViewResult
        {
            ViewName = "~/Views/Shared/Unauthorized.cshtml"
        };
    }
    

    【讨论】:

    • 我是 MVC3 的新手。我可以在上面生成任何示例解决方案(项目)吗?
    • @Hasibul,我建议您尝试自己实现它,如果遇到困难,请不要犹豫。我很乐意为您提供帮助。
    • 感谢您的解决方案。我可以做这个。在这里,用户信息写在 cookie 上。如果我在没有注销的情况下关闭浏览器,那么 cookie 仍然存在。所以这是一个问题。我怎么能克服这个?有没有办法不使用cookie进行上述操作。
    • @Hasibul,您可以使用持久性 cookie。只需在authCookie 上设置将来的到期日期,它将存储在客户端计算机上。
    • 有没有办法不使用cookie进行上述操作?如果我使用 [MyAuthorize(Roles = "Admin")] 然后“一般”角色用户被移动到登录页面,我想向他们显示拒绝访问消息。我怎样才能实现这一点。感谢您的帮助。
    猜你喜欢
    • 2016-03-07
    • 2017-08-26
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 2010-10-22
    • 2019-06-19
    • 1970-01-01
    • 2021-02-21
    相关资源
    最近更新 更多