使用JWT Bearer Token和Custom AuthorizeAttribute

时间:2016-12-07 16:38:07

标签: c# asp.net-mvc-5 oauth-2.0 asp.net-web-api2 jwt

我目前正致力于使用MVC 5Web API 2构建具有JWT和OWIN身份验证的Web API。我似乎已经按预期工作了所有这些。但是,我现在想实施角色授权,目前正在进行攻击。

我知道您可以在端点上指定Authorize属性,如下所示:

[Authorize(Roles="Admin")]

我想为基于角色的授权构建一个更强大的类型解决方案,以便更好地处理我需要的内容,这就是我遇到的问题。

现在,当用户向我的JWT端点提交usernamepassword时,我生成了oauth/token,这会在我的数据库中查找用户并返回已为用户存储的enum Flag。获取用户信息后,我为Role Claim创建ClaimsIdentity,如下所示:

private void GenerateIdentityRoles()
{
    _identity.AddClaim(new Claim(ClaimTypes.Role, _userRole.Roles.ToString()));
}

为了进一步澄清,在我生成令牌的过程中调用GenerateIdentityRoles方法,_userRole是我从数据库返回的经过验证的用户记录。 Roles参数是我存储的枚举标记。

从那里我的Bearer令牌返回给用户,然后可以用它来命中任何用[Authorize]属性修饰的端点。

有没有办法可以创建一个继承自AuthorizeAttribute类的自定义属性,该属性与[Authorize(Roles="Admin")]的工作方式相同?但是,我可以只指定[AuthorizeRolesAttribute(UserRoleEnum.Admin)]而不是指定字符串类型,然后在我的AuthorizeRolesAttribute类中从JWT Bearer Token获取传入的Roles Claim,将其转换回Enum Flag,然后检查它是否包含用HasFlag方法指定的标志?

请注意,我现在不太关心从令牌转换角色声明字符串返回,但更多是如此获取它。此外,这对我来说都是一个非常新的概念,所以我真的只是在学习。如果我的理解不正确,我完全愿意接受推理和其他解决方案。

2 个答案:

答案 0 :(得分:0)

是的,这应该是可能的。

AuthorizeAttribute进行子类化,并覆盖IsAuthorized方法。 在检查操作是否具有AllowAnonynous属性以及您不想搞砸的其他详细信息之后,这是调用特定用户是否具有访问权限的方法。 这是默认实现查看用户名和角色名称的位置,但如果您愿意,可以在此处执行完全不同的操作。

Asp.Net MVC和Web API的源代码可在Github上获得。 您可以看到AuthorizeAttribute源here

答案 1 :(得分:0)

它不一定非常复杂。

如果你想强力打字,可以使用这样的常量类: -

 public static class Constants
    {
        public static class Roles
        {
            public const string Admin = "Admin";
            public const string User = "User";
        }

    }

[Authorize(Roles=Constants.Roles.Admin)]

不需要枚举。