user2376512
user2376512

Reputation: 885

MVC user Authentication using Web API

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)
{
........
} 

Upvotes: 0

Views: 543

Answers (2)

anıl yıldırım
anıl yıldırım

Reputation: 963

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.

Upvotes: 5

Taiseer Joudeh
Taiseer Joudeh

Reputation: 9043

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.

Upvotes: 2

Related Questions