【问题标题】:Custom Authorize Attribute (follow-up)自定义授权属性(后续)
【发布时间】:2011-07-02 06:17:38
【问题描述】:

好的,跟进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 属性的方式。但是,如果覆盖属性是初始属性(基类中的那个)的不同类型,那会隐藏它还是创建一个完全不同的属性呢?

那你怎么看?这真的应该工作吗?我现在无法测试它,因为我还没有设置UI(等待设计师完成设计)......事实上,这是我第一次体会到TDD的好处,我曾经认为它完全愚蠢而无用,但我错了:)

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

提前致谢。

【问题讨论】:

  • 不要将安全敏感信息放在Session 中,这不是为了保证安全。谷歌“ASP.NET 会话劫持”。
  • 我实际上并没有在 Session 中放入任何敏感信息。 Session 中的不是 User 对象本身,它是一个包含两个属性的对象:用户 ID 和昵称。这会牺牲任何重要数据吗?
  • 用户的身份可能是可以想象到的最安全敏感的信息。如果我可以伪装成你,那么我可以做任何你能做的事情。
  • 不,使用 SSL 并不能阻止这种情况。使用 SSL 可以确保 客户端 他们正在与您交谈。它不会验证客户对其身份的声明。
  • 您仍然没有说明您的实际问题。你只是坚持认为其他人使用的解决方案不可能工作。请原谅我这么说,但它们并没有你在这里提出的一半那么糟糕。因此,与其坚持认为一个非常灵活的系统可能无法为您工作,不如解释一下您要解决的业务问题,并为寻求最佳解决方案。

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


【解决方案1】:
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();
}

【讨论】:

    猜你喜欢
    • 2011-07-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    相关资源
    最近更新 更多