首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

MVC AuthorizeAttribute 控制用户跳转,action方法还是被执行了 有关问题

2013-12-10 
MVCAuthorizeAttribute 控制用户跳转,action方法还是被执行了 问题ASP.NET MVC 3 自学ing我想用FormsAuthe

MVC AuthorizeAttribute 控制用户跳转,action方法还是被执行了 问题
ASP.NET MVC 3 自学ing

我想用FormsAuthentication来控制权限,

我要的很简单:
没有登录就访问,则跳到登录页面
登录后没权限访问,则提示“无权访问”,不要跳转到登录页面
我实现后 结果发现 被限制的action方法还是会被执行一次,过后页面才显示“无权访问”

我实现的方法如下:

继承AuthorizeAttribute,重写OnAuthorization方法:

public class OperatorAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var formId = HttpContext.Current.User.Identity as FormsIdentity;
            if (formId != null && formId.IsAuthenticated)
            {
                var rolesTemp = formId.Ticket.UserData.Split('&');
                var roles = rolesTemp[0];
                if (!Roles.Contains(roles))
                {
                    filterContext.RequestContext.HttpContext.Response.Write("无权访问");
                    filterContext.RequestContext.HttpContext.Response.End();    
                }
                else
                {
                    FormsAuthentication.RedirectFromLoginPage(formId.Name,false);
                }
            }
            else
            {
                FormsAuthentication.RedirectToLoginPage();
            }
        }
    }

控制器中:(登录后权限编码不在3,25,26,27,28,29中的就提示“无权访问”)
[OperatorAuthorize(Roles = "3,25,26,27,28,29")]
        public ViewResult Index(int? currentPage)
        {
            int currentIndex = currentPage.HasValue ? currentPage.Value : 1;
            int pageSize = CommonAction.GetPageSize();
            int total = db.Clients.Count();
            ViewBag.PageHTML = new WebDataPage().GetPageHTML(currentIndex, total, pageSize, CommonAction.GetAppIntByName("ShowNumber"));
            int topIndex = (currentIndex - 1) * pageSize;
            var query = db.Clients.OrderBy(em => em.ClientID).Skip(topIndex).Take(pageSize).ToList();
            return View(query);
        }

断点调试 权限限制成功,并提示“无权访问”

但是 断点调试的时候action方法Index还是被执行了一次,执行完了 才显示“无权访问”,如何解决 ?
我想实现 没有权限就不执行index方法。如何实现 

[解决办法]
重写HandleUnauthorizedRequest方法
/// <summary>
        /// 用于处理验证失败后的方法
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)


        {
            //filterContext.HttpContext.Response.Redirect("/Login?back=" + filterContext.HttpContext.Request.Url.ToString());
            filterContext.Result = new RedirectResult("/Login?back=" + filterContext.HttpContext.Request.Url.ToString());
        }
[解决办法]
Protected Overrides Function AuthorizeCore(ByVal httpContext As System.Web.HttpContextBase) As Boolean


应该在这里重写判断,如果判断失败就抛出404错误
[解决办法]
自定义AuthorizeAttribute 网站的权限判断是一个非常普遍的需求,从文章ASP.NET MVC的Action Filter中我们知道实现这样的需求只要从AuthorizeAttribute集成,重写相关的判断逻辑就可以了。这里记录一下:

namespace TokenAcl.Web.Helper 

    public class TokenAclAuthorizeAttribute : AuthorizeAttribute 
    { 
        protected override bool AuthorizeCore(HttpContextBase httpContext) 
        { 
            bool result = false; 
            if (httpContext == null) 
            { 
                throw new ArgumentNullException("httpContext"); 
            } 
            string[] users = Users.Split(','); 
            string[] roles = Roles.Split(','); 
            if (!httpContext.User.Identity.IsAuthenticated) 
                return false; 
            if (roles.Length != 0) 
            { 
                List<Role> rightRoles = RightClient.GetAllRole(TakenAclMenu.SystemID, TakenAclMenu.UserID); 
                foreach (var role in roles) 
                { 
                    if (rightRoles.Where(x => x.Code == role).Count() > 0) 
                    { 
                        result = true; 
                        break; 
                    } 
                } 
            } 
            if (!result) 
            { 
                httpContext.Response.StatusCode = 403; 
            } 
            return result; 
        }

        public override void OnAuthorization(AuthorizationContext filterContext) 
        { 
            base.OnAuthorization(filterContext); 
            if (filterContext.HttpContext.Response.StatusCode == 403) 
            { 
                filterContext.Result = new RedirectResult("/Admin/Dashboard"); 
            } 
        } 
    } 
}

从AuthorizeAttribute继承过来实现了一个类TokenAclAuthorizeAttribute ,重写了方法AuthorizeCore,使用自己开发的权限系统进行权限的验证,如果没有通过认证,这表示没有权限访问,设置HTTP 状态代码为403。 这样还是不行,还得重写另一个方法OnAuthorization。AuthorizeCore方法返回false,MVC 此时将返回的ActionResult是HttpUnauthorizedResult:

public class HttpUnauthorizedResult : ActionResult { 


public override void ExecuteResult(ControllerContext context) { 
if (context == null) { 
throw new ArgumentNullException("context"); 
            } 
// 401 is the HTTP status code for unauthorized access - setting this 
// will cause the active authentication module to execute its default 
// unauthorized handler 
            context.HttpContext.Response.StatusCode = 401; 
        } 
    }

从HttpUnauthorizedResult的源码可以看出,HttpUnauthorizedResult的执行很简单,就是设置当前的HttpContext.Response的状态码为401,这样就回激活authentication module 执行它默认的 unauthorized handler,也就是跳转到登陆页面的,这似乎也不符合逻辑,认证和授权应该是验证的两个方面。这不符合要求,用户已经登陆成功了,只是没有权限而已。我这里只是重写OnAuthorization方法,重定向到一个页面而已,也可以写一个ActionResult。


[解决办法]
你有查看相关资料吗?先在OnAuthorization方法里做判断,在跳转
 public override void OnAuthorization(AuthorizationContext filterContext)
{
            if("没权限"){
              return false;
            }
            else {
                return true;
            }
}

热点排行