简体   繁体   English

使用JWT承载令牌和自定义AuthorizeAttribute标记角色枚举

[英]Flag Role Enum with JWT Bearer Token and Custom AuthorizeAttribute

I am currently working on building a Web API that has JWT and OWIN authentication using MVC 5 and Web API 2 . 我目前正在使用MVC 5Web API 2构建具有JWT和OWIN身份验证的Web API 2 I seem to have all of that working as intended. 我似乎所有的工作都按预期进行。 However, I would now like to implement Roles authorization and am currently hitting a wall. 但是,我现在想实施Roles授权,并且目前遇到了麻烦。

I know that on your endpoints you can specify the Authorize attribute like this: 我知道您可以在端点上指定Authorize属性,如下所示:

[Authorize(Roles="Admin")]

I would like to build a stronger typed solution for Role based authorization to better handle what I need, and this is where I have hit a wall. 我想为基于角色的授权构建一个更强大的类型化解决方案,以更好地处理我所需要的东西,这就是我遇到的麻烦。

Right now I have my JWT being generated when a user submits a username and password to my oauth/token endpoint this looks up the user in my database and returns a enum Flag that has been stored for the user. 现在,当用户向我的oauth/token端点提交usernamepassword ,我将生成JWT ,这将在数据库中查找该用户并返回已为该用户存储的enum Flag After obtaining the user information I create a Role Claim for my ClaimsIdentity like so: 获取用户信息后,我将为我的ClaimsIdentity创建一个Role ClaimClaimsIdentity所示:

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

Just for further clarification the GenerateIdentityRoles method is called in my process of generating the token and _userRole is my verified user record returned from the database. 为了进一步说明,在GenerateIdentityRoles令牌的过程中调用了GenerateIdentityRoles方法,而_userRole是我从数据库返回的经过验证的用户记录。 The Roles param is my stored enum flag. Roles参数是我存储的枚举标志。

From there my Bearer token gets returned to the user where it can then be used to hit any endpoint decorated with an [Authorize] attribute. 从那里,我的Bearer令牌返回给用户,然后可以用它来命中任何装饰有[Authorize]属性的端点。

Is there a way that I could create a custom attribute that is inherited from the AuthorizeAttribute class that would work the same way as [Authorize(Roles="Admin")] ? 有没有一种方法可以创建从AuthorizeAttribute类继承的自定义属性,该自定义属性的工作方式与[Authorize(Roles="Admin")] However, instead of the string type being specified I could just specify [AuthorizeRolesAttribute(UserRoleEnum.Admin)] and then inside my AuthorizeRolesAttribute class take the incoming Roles Claim from the JWT Bearer Token, convert it back to the Enum Flag, and then check to see if it contains the flag specified with the HasFlag method? 但是,除了指定字符串类型外,我还可以指定[AuthorizeRolesAttribute(UserRoleEnum.Admin)] ,然后在我的AuthorizeRolesAttribute类中,从JWT Bearer令牌中获取传入的Roles Claim ,将其转换回Enum Flag,然后检查看看它是否包含用HasFlag方法指定的标志?

Please note that I am not too concerned at the moment with converting the Role Claim string return from the token, but more so obtaining it. 请注意,目前我不太担心转换令牌中的Role Claim字符串返回,但更重要的是获取它。 Also, this is all a very new concept for me so I am really just learning as I go. 另外,这对我来说是一个非常新的概念,所以我实际上只是在学习。 If any of my understanding is incorrect, I am completely open to reasoning and other solutions. 如果我的理解有误,我将完全接受推理和其他解决方案。

Yes, this should be possible. 是的,这应该可行。

Subclass the AuthorizeAttribute , and override the IsAuthorized method. 子类AuthorizeAttribute ,并重写IsAuthorized方法。 This is the method that is called to check if a specific user has access, after checking if the action had an AllowAnonynous attribute and other details you don't want to mess with. 在检查操作是否具有AllowAnonynous属性和您不想弄乱的其他详细信息之后,调用此方法来检查特定用户是否具有访问权限。 This is where the default implementation looks at the username and role name, but you can do something completely different here if you want to. 这是默认实现查看用户名和角色名称的地方,但是如果需要,您可以在此处执行完全不同的操作。

The source code of Asp.Net MVC and Web API is available on Github. Github上提供了Asp.Net MVC和Web API的源代码。 You can see the AuthorizeAttribute source here . 您可以在此处看到AuthorizeAttribute源。

It doesn't have to be that complicated. 不必那么复杂。

If you want to make it strongly typed you could use a Constants class like this :- 如果要使其强类型化,则可以使用这样的Constants类:

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

    }

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

There's no need for enums. 不需要枚举。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM