自定义授权属性(后续)

时间:2011-02-22 19:32:51

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

好的跟进this thread,这就是我想出的......

public class SharweAuthorizeAttribute : AuthorizeAttribute
{
    private bool isAuthenticated = false;
    private bool isAuthorized = false;
    public new string[] Roles { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (SessionManager.CheckSession(SessionKeys.User) == true)
        {
            isAuthenticated = true;
            foreach (string role in Roles)
            {
                if (RolesService.HasRole((string)role))
                    isAuthorized = true;
            }
        }
        return (isAuthenticated && isAuthorized);
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!isAuthenticated)
        {
            filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary 
                            {
                                { "action", "User" },
                                { "controller", "Login" }
                            });
        } else if(!isAuthorized) {
            filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary 
                            {
                                { "action", "Home" },
                                { "controller", "Error" }
                            });
        }
    }
}

我是如何/为什么想出这个?因为我相信AuthorizeAttribute工作流程如下:

  1. 首先,触发AuthorizeCore。如果返回true,则授权用户。如果返回false,则触发HandleUnauthorizedRequest。是吗?
  2. 我在某处读到了我需要使用new关键字来覆盖属性。因此,这就是我覆盖Roles属性的方式。但是如果覆盖属性是初始属性的不同类型(基类中的属性),那么它是否也会隐藏它或创建一个完全不同的属性呢?
  3. 那你觉得怎么样?这真的有用吗?我现在无法测试它,因为我没有设置UI(等待设计师完成设计)......事实上,这是我第一次欣赏TDD的好处,我曾经认为它是完全的愚蠢无用,但我错了:)

    P.S:在this thread上,@ tvanfosson正在设置上下文的CachePolicy(我想),有人可以解释一下,为什么我可能需要这样做呢?

    提前致谢。

1 个答案:

答案 0 :(得分:2)

public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        private readonly bool _authorize;
        private readonly string[] _roles;
        public CustomAuthorizeAttribute(string roles)
        {
            _authorize = true;
            _roles = roles.Split(',');
        }

        public CustomAuthorizeAttribute(string roles, bool isAdminPath)
        {
            _authorize = true;
            _roles = roles.Split(',');
        }



        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {


            //if controller have role auth and user is not loged
            if(_authorize && !httpContext.User.Identity.IsAuthenticated)
            {
                return false;
            }

            // if controller have role auth and user is loged
            if(_roles != null)
            {

                //grab user roles from DB
                var UserRole = RoleRepository.GetUserRole(new Guid(httpContext.User.Identity.Name));
                if (_roles.Contains(UserRole))
               {
                   return true;
               }

            }

            return false;

        }
    }

在控制器

    [CustomAuthorize("Administrator,Company,OtherRole")]
    public ActionResult Test(){

    return View();
    }