0

I have built a WebAPI for user login, the webAPI can generate Access Token, if the user provided correct UserName and password. My Question is how I can pass user role information to the MVC application also.

For example,

I have a MVC app controller below, how can I pass the role 'Admin, UserEditor' from the Web API? I know I can use another WebAPI call to check user role, but it is not a good idea to do it.

[Authorized("Admin,UserEditor")]
ActionResult EditUser(int? Id)
{
........
} 

2 Answers 2

5
+50

You can read role information from claims.

Step-1 Create Role-s

I created it seed, but your choice may be different.

public static class MyDbInitializer
    {
        public static void Seed(this ModelBuilder builder)
        {
            Guid adminRoleId = Guid.Parse("90a5d1bb-2cf0-4014-9f1a-2d9f644a2e22");

            builder.Entity<IdentityRole<Guid>>().HasData(
                new IdentityRole<Guid>
                {
                    Id = adminRoleId,
                    Name = RoleIdentifier.admin,
                    NormalizedName = RoleIdentifier.admin.ToUpper(CultureInfo.GetCultureInfo("en-GB"))
                });

        }
    }

Step-2 Claims

  public static class RoleIdentifier
    {
        public const string admin = "admin";
        public const string user = "user";
    }

public static class JwtClaimIdentifier
    {
        public const string UserId = "user_id";
        public const string UserName = "user_name";
        public const string Role = "role";
    }

Where you generate tokens, add the role name to the claims information.

...
... string role = await _userService.GetRole(userId);
... identity.FindFirst(JwtClaimIdentifier.Role)

Step-3 Add authorize att. to controllers.

 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = RoleIdentifier.admin)]
    public class FooController
    {
    }

When the logged in user wants to access this action, the possession of this role will match and access claims.

Sign up to request clarification or add additional context in comments.

Comments

2

You need to use 2 authentication mechanisms (Bearer Tokens, and Cookies) because your are securing Web API end points using tokens and MVC 5 controllers using Cookies. I recommend you to check VS 2013 Web template with MVC core dependency selected. It contains all the code needed at your case. Inside the GrantResourceOwnerCredentials method you will find something similar to the below:

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }

        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
            CookieAuthenticationDefaults.AuthenticationType);

        AuthenticationProperties properties = CreateProperties(user.UserName);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

Notice how there are oAuthIdentity for Web API, and cookiesIdentity for MVC application.

1 Comment

Thanks your reply! Do you mean that I have to custom GrantResourceOwnerCredentials and check the AccessToken in cookie? I got another question here, how my MVC application to get the claim info from WebAPI. If the WebAPI and MVC are not in the same domain, Do they need to share the machine key?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.