当角色分配更改时,授权令牌仍会向用户显示旧角色

时间:2015-11-12 19:25:33

标签: c# asp.net asp.net-web-api asp.net-identity

我基本上有这里描述的设置:http://blogs.msdn.com/b/martinkearn/archive/2015/03/25/securing-and-working-securely-with-web-api.aspx

问题是,如果在收到令牌后修改了用户的角​​色,则除非用户再次登录并收到新令牌,否则不会反映更改。

例如:

  • 用户处于角色" ABC"
  • 用户登录,接收令牌
  • 用户使用令牌访问装饰的端点[授权(角色=" ABC")](如预期的那样)
  • 管理员将用户从角色" ABC"
  • 中删除
  • 用户仍然可以使用令牌访问装饰的端点[授权(角色=" ABC")] (意外)
  • 用户丢弃令牌,再次登录,收到新令牌
  • 用户使用新令牌访问使用[授权(角色=" ABC")]修饰的端点并获取401(按预期方式)

换句话说,除非用户请求新令牌(再次登录),否则HttpContext.Current.User.IsInRole(" ABC")将返回true,即使AspNetUserRoles表显示用户不是有这个角色。

在对AspNetUserRoles表进行更改时,如何更新(或可能使作者无效?)令牌?

1 个答案:

答案 0 :(得分:1)

令牌存储身份信息(用户名,ID)以及用户登录时的所有角色。这样做是为了使每次需要检查权限时都不必在数据库中查找用户信息,但它的缺点是在角色信息发生变化时不会改变。

如果您每次都能访问数据库,我会通过继承AuthorizeAttribute并覆盖OnAuthorization方法来构建自定义Authorize属性。如果您不想在每个角色检查中访问数据库,您仍然可以填充角色最近更改时的缓存,并且只有在该用户的角色更新日期晚于票证日期时才会访问数据库。 / p>

例如:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAuthenticated)
        {
            // Redirect to login page
            filterContext.Result = Redirect("Login", "Index");
            return;
        }

        var roles = GetRolesFromDb();
        if (!Roles.Any(r => roles.Contains(r)))
            filterContext.Result = Redirect("Error", "AccessDenied");
    }

    private RedirectToRouteResult Redirect(string controller, string action, string area = "")
    {
        return new RedirectToRouteResult(new RouteValueDictionary(new
        {
            controller,
            action,
            area,
        });
    }
}