Asp.net 使用webapi的MVC用户身份验证

Asp.net 使用webapi的MVC用户身份验证,asp.net,asp.net-mvc,asp.net-web-api,Asp.net,Asp.net Mvc,Asp.net Web Api,我已经为用户登录构建了一个WebAPI,如果用户提供了正确的用户名和密码,WebAPI可以生成访问令牌。我的问题是如何将用户角色信息也传递给MVC应用程序 比如说, 我下面有一个MVC应用程序控制器,如何从Web API传递角色“Admin,UserEditor”?我知道我可以使用另一个WebAPI调用来检查用户角色,但这样做不是一个好主意 [Authorized("Admin,UserEditor")] ActionResult EditUser(int? Id) { ........ }

我已经为用户登录构建了一个WebAPI,如果用户提供了正确的用户名和密码,WebAPI可以生成访问令牌。我的问题是如何将用户角色信息也传递给MVC应用程序

比如说,

我下面有一个MVC应用程序控制器,如何从Web API传递角色“Admin,UserEditor”?我知道我可以使用另一个WebAPI调用来检查用户角色,但这样做不是一个好主意

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

您需要使用2种身份验证机制(承载令牌和cookie),因为您使用令牌和使用cookie的MVC5控制器来保护Web API端点。我建议您在选中MVC核心依赖项的情况下检查VS 2013 Web模板。它包含您的案例所需的所有代码。在
GrantResourceOwnerCredentials
方法中,您会发现类似以下内容:

        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);
    }
public override异步任务GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext)
{
var userManager=context.OwinContext.GetUserManager();
ApplicationUser user=await userManager.FindAsync(context.UserName,context.Password);
if(user==null)
{
SetError(“无效的授权”,“用户名或密码不正确”);
回来
}
ClaimsIdentity oAuthIdentity=等待用户.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimSideEntity cookiesIdentity=等待用户.GenerateUserIdentity异步(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties=CreateProperties(user.UserName);
AuthenticationTicket=新的AuthenticationTicket(OAuthidentitity,属性);
上下文。已验证(票证);
context.Request.context.Authentication.sign(cookiesIdentity);
}

请注意,Web API和MVC应用程序分别有
oAuthIdentity和
cookiesIdentity

您可以从声明中读取角色信息

第一步创建角色

  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";
    }
我创造了它的种子,但你的选择可能会有所不同

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"))
                });

        }
    }
在生成令牌的地方,将角色名称添加到索赔信息中

...
... string role = await _userService.GetRole(userId);
... identity.FindFirst(JwtClaimIdentifier.Role)
步骤3将授权附件添加到控制器。

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

当登录用户想要访问此操作时,此角色的拥有权将匹配并访问声明。

谢谢您的回复!你的意思是我必须自定义GrantResourceOwnerCredentials并检查cookie中的AccessToken吗?我这里还有一个问题,我的MVC应用程序如何从WebAPI获取索赔信息。如果WebAPI和MVC不在同一个域中,它们是否需要共享机器密钥?