属性要求的用户,而不是登录访问否认? [英] attribute asks user to login instead of access denied?

查看:155
本文介绍了属性要求的用户,而不是登录访问否认?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 公共类CustomAuthorize:AuthorizeAttribute
{
    保护覆盖无效HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        //返回HTTP 401 - 见注释中HttpUnauthorizedResult.cs
        //如果用户没有登录提示
        如果(!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        //否则拒绝访问
        其他
        {
            filterContext.Result =新RedirectToRouteResult(
                新RouteValueDictionary {
                {控制器,帐户},
                {行动,NotAuthorized}
            });
        }
    }
}


我从开始的NerdDinner和正在使用FormsAuthentication与ActiveDirectory中为我的会员供应商。我已经通过我的分贝的Global.asax和放大器增加了对角色的支持;的AccountController(如下图)。

所以,现在在我的控制器我有我的授权属性设置为管理员的角色,只(见下文)。我登录的用户是一位作家。当我点击删除它问我,即使我已经这样做了登录。我在哪里可以把逻辑返回访问被拒绝的看法?

的Global.asax.cs

 保护无效Application_AuthenticateRequest(对象发件人,EventArgs的发送)
    {
        的HttpCookie authCookie = Context.Request.Cookies [FormsAuthentication.FormsCookieName]
        如果(authCookie == NULL || authCookie.Value ==)
        {
            返回;
        }        的FormsAuthenticationTicket authTicket = NULL;        尝试
        {
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        }
        抓住
        {
            返回;
        }        如果(Context.User!= NULL)
        {
            字符串[] =角色authTicket.UserData.Split(新的char [] {','});
            Context.User =新的GenericPrincipal(Context.User.Identity,角色);
        }
    }

AccountController.cs

  [HttpPost]
    [System.Diagnostics程序codeAnalysis.Sup pressMessage(Microsoft.Design,CA1054:UriParametersShouldNotBeStrings。
        理由=需要采取相同的参数类型Controller.Redirect())
    公众的ActionResult登录(用户名字符串,字符串密码,布尔与rememberMe,串RE​​TURNURL)
    {        如果(!ValidateLogOn(用户名,密码))
        {
            计算机[了rememberMe] =与rememberMe;
            返回查看();
        }        //确保我们有正确的大写的用户名
        //因为我们做的情况下,对OpenID的敏感检查声称标识符后。
        的userName = this.MembershipService.GetCanonicalUsername(用户名);        //查找用户(CWID)适当的访问级别
        字符串ACCESSLEVEL = userRepository.FindUserByUserName(用户名).AccessLevel.LevelName;        的FormsAuthenticationTicket authTicket =新
                        的FormsAuthenticationTicket(1,//版本
                        用户名,//用户名
                        DateTime.Now,//创建
                        DateTime.Now.AddMinutes(30),//到期
                        与rememberMe,//持续
                        ACCESSLEVEL); //砍死使用角色,而不是        字符串encTicket = FormsAuthentication.Encrypt(authTicket);
        this.Response.Cookies.Add(新的HttpCookie(FormsAuthentication.FormsCookieName,encTicket));        如果(!String.IsNullOrEmpty(RETURNURL))
        {
            返回重定向(RETURNURL);
        }
        其他
        {
            返回RedirectToAction(指数,家);
        }
    }

SpotlightController.cs

  [授权(角色=管理员)]
    公众的ActionResult删除(INT ID)


解决方案

下面是AuthorizeAttribute呢,出的最框:它检查当前用户是否被授权当前请求,并返回HHTP 401 / UNAUTHORIZED如果它们不是,或者是因为它们没有登录在所有,或它们不是授权用户的清单上/当前请求的作用。

借助 Web表单验证HTTP模块看到这个401响应,截获,并把它变成一个HTTP 302 (重定向)响应到登录页面,如果loginUrl属性在web.config中配置。总的想法是,如果用户被拒绝访问该网站,因为他们还没有登录,但他们会想要做的下一件事就是登录

既然你想要做的是在其他地方重新定向什么,覆盖HandleUnauthorizedRequest和重定向的哈尔的建议是没有道理的。只要记住,如果你仍然希望非认证用户看到的登录页面(而不是通过身份验证,而不是在允许的用户/角色的列表),那么你将不得不添加逻辑的。我建议不要覆盖AuthorizeCore或OnAuthorization的想法;这些都不真正解决这个问题,他们更容易比HandleUnauthorizedRequest搞砸了。

Updated: Thanks to the help here I've created the following solution:

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"}
            });
        }
    }
}


I started from NerdDinner and am using FormsAuthentication with ActiveDirectory as my membership provider. I've added support for roles via my db with Global.asax & AccountController (below).

So now in my controller I have my Authorize attribute set to roles of admin only (below). My logged in user is an author. When I click delete it asks me to login even though I have already done so. Where can I put the logic to return an access denied view?

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);
        }
    }

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");
        }
    }

SpotlightController.cs

    [Authorize(Roles="Admin")]
    public ActionResult Delete(int id)

解决方案

Here is what AuthorizeAttribute does, out-of-the-box: It checks to see if the current user is authorized for the current request, and returns HHTP 401/UNAUTHORIZED if they are not, either because they are not logged in at all, or they are not on the list of authorized users/roles for the current request.

The Web forms authentication HTTP module sees this 401 response, intercepts that, and turns it into an HTTP 302 (redirect) response to the login page, if the loginUrl attribute is configured in web.config. The general thought is that if a user is denied access to the site because they are not logged in, but the next thing they will want to do is log in.

Since what you want to do is redirect elsewhere, Hal's suggestion of overriding HandleUnauthorizedRequest and redirecting is not unreasonable. Just bear in mind that if you still want non-authenticated users to see the login page (as opposed to authenticated, but not in the list of permitted users/roles), then you will have to add logic for that. I would advise against the idea of overriding AuthorizeCore or OnAuthorization; neither of these actually solve the problem, and they are much easier to screw up than HandleUnauthorizedRequest.

这篇关于属性要求的用户,而不是登录访问否认?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆