代码之家  ›  专栏  ›  技术社区  ›  ryan

属性要求用户登录而不是拒绝访问?

  •  7
  • ryan  · 技术社区  · 16 年前

    感谢这里的帮助,我创建了以下解决方案:

    public class CustomAuthorize : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs
            // If user is not logged in prompt
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
            // Otherwise deny access
            else
            {
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary {
                    {"controller", "Account"},
                    {"action", "NotAuthorized"}
                });
            }
        }
    }
    

    我从NerdDinner开始使用FormsAuthentication和ActiveDirectory作为我的成员资格提供者。我已经通过我的db with Global.asax&添加了对角色的支持;AccountController(下图)。

    所以现在在我的控制器中,我将Authorize属性设置为roles of admin only(如下)。我的登录用户是作者。当我点击删除它要求我登录,即使我已经这样做了。我可以将返回拒绝访问视图的逻辑放在哪里?

    全球.asax.cs

        protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        {
            HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie == null || authCookie.Value == "")
            {
                return;
            }
    
            FormsAuthenticationTicket authTicket = null;
    
            try
            {
                authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            }
            catch
            {
                return;
            }
    
            if (Context.User != null)
            {
                string[] roles = authTicket.UserData.Split(new char[] { ';' });
                Context.User = new GenericPrincipal(Context.User.Identity, roles);
            }
        }
    

    会计控制器.cs

        [HttpPost]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
            Justification = "Needs to take same parameter type as Controller.Redirect()")]
        public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
        {
    
            if (!ValidateLogOn(userName, password))
            {
                ViewData["rememberMe"] = rememberMe;
                return View();
            }
    
            // Make sure we have the username with the right capitalization
            // since we do case sensitive checks for OpenID Claimed Identifiers later.
            userName = this.MembershipService.GetCanonicalUsername(userName);
    
            // Lookup user's (CWID) appropriate access level
            string accessLevel = userRepository.FindUserByUserName(userName).AccessLevel.LevelName;
    
            FormsAuthenticationTicket authTicket = new
                            FormsAuthenticationTicket(1, //version
                            userName, // user name
                            DateTime.Now,             //creation
                            DateTime.Now.AddMinutes(30), //Expiration
                            rememberMe, //Persistent
                            accessLevel); // hacked to use roles instead
    
            string encTicket = FormsAuthentication.Encrypt(authTicket);
            this.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
    
            if (!String.IsNullOrEmpty(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
    

    聚光灯控制器.cs

        [Authorize(Roles="Admin")]
        public ActionResult Delete(int id)
    
    3 回复  |  直到 16 年前
        1
  •  5
  •   Craig Stuntz    16 年前

    AuthorizeAttribute的作用是:检查当前用户是否被授权处理当前请求,如果没有,则返回HHTP 401/UNAUTHORIZED,原因可能是他们根本没有登录,或者他们不在当前请求的授权用户/角色列表中。

    这个 Web forms authentication HTTP module sees this 401 response, intercepts that, and turns it into an HTTP 302 (redirect) response to the login page ,如果在web.config中配置了loginUrl属性。一般的想法是,如果一个用户因为没有登录而被拒绝访问该站点,那么接下来他们要做的就是登录。

    因为你想做的是重定向到其他地方,哈尔的建议,推翻HandleUnauthorizedRequest和重定向是合理的。请记住,如果您仍然希望未通过身份验证的用户看到登录页(与通过身份验证的用户相反,但不在允许的用户/角色列表中),那么您必须为此添加逻辑。我建议不要把授权凌驾于核心或授权之上;这两种方法实际上都不能解决问题,而且它们比处理授权请求更容易出错。

        2
  •  2
  •   Hal    16 年前

    哈尔

        3
  •  1
  •   kmehta    16 年前