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

rya*_*yan 7 c# forms-authentication roles asp.net-mvc-2

更新:感谢此处的帮助,我创建了以下解决方案:

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"}
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我从NerdDinner开始,使用FormsAuthentication和ActiveDirectory作为我的会员提供者.我通过我的数据库使用Global.asax和AccountController(下面)添加了对角色的支持.

所以现在在我的控制器中,我的Authorize属性设置为仅限admin的角色(下面).我登录的用户是作者.当我点击删除时,它会要求我登录,即使我已经这样做了.我在哪里可以使用逻辑返回拒绝访问视图?

的Global.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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

AccountController.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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

SpotlightController.cs

    [Authorize(Roles="Admin")]
    public ActionResult Delete(int id)
Run Code Online (Sandbox Code Playgroud)

Cra*_*ntz 5

这是AuthorizeAttribute的功能,开箱即用:它检查当前用户是否有权获得当前请求,如果不是,则返回HHTP 401/UNAUTHORIZED,因为它们根本没有登录,或者它们不在当前请求的授权用户/角色列表中.

Web表单认证HTTP模块认为这401响应,截获,并把它变成一个HTTP 302(重定向)响应于所述登录页面,如果loginUrl属性web.config中配置.一般的想法是,如果用户因为没有登录而被拒绝访问该站点,但他们想要做的下一件事就是登录.

由于您想要做的是重定向到其他地方,Hal的建议覆盖HandleUnauthorizedRequest和重定向并不是不合理的.请记住,如果您仍然希望未经过身份验证的用户能够看到登录页面(与经过身份验证的用户相反,而不是在允许的用户/角色列表中),那么您必须为此添加逻辑.我建议反对覆盖AuthorizeCore或OnAuthorization的想法; 这些都没有真正解决问题,而且它们比HandleUnauthorizedRequest更容易搞砸.