简体   繁体   中英

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 . 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.

I know that on your endpoints you can specify the Authorize attribute like this:

[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. After obtaining the user information I create a Role Claim for my ClaimsIdentity like so:

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. The Roles param is my stored enum flag.

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.

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")] ? 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?

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. 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. 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. 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. You can see the AuthorizeAttribute source here .

It doesn't have to be that complicated.

If you want to make it strongly typed you could use a Constants class like this :-

 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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