自定义授权属性(后续)

4

好的,跟进这个帖子,以下是我想到的...

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的好处,我曾经认为它非常愚蠢和无用,但我错了 :)
附注:在这个线程上,@tvanfosson正在设置上下文的CachePolicy(我想),有人能解释一下为什么我可能需要这样做吗?
谢谢。

1
请勿将安全敏感信息放入“Session”中,因为它并不是安全的。请搜索“ASP.NET会话劫持”。 - Craig Stuntz
我实际上没有在Session中放置任何敏感信息。Session中的内容不是用户对象本身,而是包含两个属性的对象:用户ID和昵称。这是否会牺牲任何重要数据? - Kassem
1
用户身份可能是最敏感的信息。如果我能冒充你,那么我就可以做任何你能做的事情。 - Craig Stuntz
3
不,使用SSL并不能防止这种情况。使用SSL确保客户端正在与您通信,但它并不验证客户端对其身份的声明。 - Craig Stuntz
1
你仍然没有说明你的实际问题。你只是坚持认为其他人使用的解决方案不可能起作用。请原谅我这么说,但它们并没有你在这里提出的东西那么糟糕。因此,与其坚持认为一个非常灵活的系统对你来说不可能起作用,为什么不解释一下你试图解决的业务问题,并寻求最佳解决方案呢? - Craig Stuntz
显示剩余8条评论
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接