授权和GetRoles在ASP.NET身份中不起作用 [英] Authorize and GetRoles doesn't work in ASP.NET Identity

查看:204
本文介绍了授权和GetRoles在ASP.NET身份中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP.NET Identity 2.1.0使用实体框架实现。

验证工作正常,但基于角色的安全性有问题。
虽然我已经为用户添加了角色,但是这个代码返回空:

  var roles = UserManager.GetRoles User.Identity.GetUserId()); 

同时基于登录用户角色的授权失败。当用户重定向到如下应用程序的控制器时,将他重定向到登录页面。

  [授权(Roles =Admin)] 
public abstract partial class AdminAreaController:Controller
{

为了添加ASP .NET Identity,首先,我创建了自定义用户类添加配置文件数据:

  public class BasemapUser:IdentityUser 
{
[MaxLength(100)]
public string Name {get;组; }

[MaxLength(100)]
public string CompanyName {get;组; }

public async任务< ClaimsIdentity> GenerateUserIdentityAsync(UserManager< BasemapUser> manager)
{
//请注意,authenticationType必须与CookieAuthenticationOptions.AuthenticationType中定义的那个匹配。
ClaimIdentity userIdentity =
await manager.CreateIdentityAsync(this,DefaultAuthenticationTypes .ApplicationCookie);
//在此添加自定义用户声明
return userIdentity;
}
}

这是DbContext类:

  public class WebCoreMapDbContext:IdentityDbContext< BasemapUser> 
{
public WebDbContext()
:base(WebDbContext)
{
}

public static WebCoreMapDbContext Create()
{
返回新的WebCoreMapDbContext();
}


protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity< IdentityUserLogin>()。HasKey< string>(l = > l.UserId);
modelBuilder.Entity< IdentityUserRole>()。HasKey(r => new {r.RoleId,r.UserId});
}
}

我在power shell中创建了使用EF Migration命令的数据库。我在IdentityUserRoles表中看到两个额外的列,我在ASP.NET身份的其他示例中没有看到。





我使用此代码添加默认的管理员用户和角色:

  public static void Start()
{
var userManager = HttpContext.Current.GetOwinContext()。GetUserManager< BasemapUserManager>() ;
var roleManager = HttpContext.Current.GetOwinContext()。Get< ApplicationRoleManager>();
const string name =someEmail@gmail.com;
const string password =somePassword;
const string roleName =Admin;

//创建角色管理(如果不存在)
IdentityRole角色= roleManager.FindByName(roleName);
if(role == null)
{
role = new IdentityRole(roleName);
IdentityResult roleresult = roleManager.Create(role);
}

BasemapUser user = userManager.FindByName(name);
if(user == null)
{
user = new BasemapUser {UserName = name,Email = name};
IdentityResult result = userManager.Create(user,password);
result = userManager.SetLockoutEnabled(user.Id,false);
}

//如果尚未添加,请将角色管理员添加到角色管理员
IList< string> rolesForUser = userManager.GetRoles(user.Id);
if(!rolesForUser.Contains(role.Name))
{
IdentityResult result = userManager.AddToRole(user.Id,role.Name);

}
}

管理员用户和角色已被存储在数据库中成功但在IdentityUserRoles表中存储的记录包含空值:





为什么GetRoles对于在数据库中具有该角色的用户没有返回任何内容?还有其他API,如IsInRole不能按预期工作。是因为外键添加到IdentityUserRoles表中吗?

解决方案

问题是已添加到Identity表中的不必要的列。



由于DbContext从IdentityDbContext扩展,所以我必须调用base.OnModelCreating,因为IdentityDbContext定义它用于映射身份类。我没有在我导致问题的代码中调用这个问题

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity< IdentityUserLogin>()。HasKey< string>(l => l.UserId);
modelBuilder.Entity< IdentityUserRole>()。HasKey(r => new {r.RoleId,r.UserId});
}

要更改为

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

// modelBuilder.Entity< IdentityUserLogin>()。HasKey< string>(l => l.UserId); //不要添加
// modelBuilder.Entity< IdentityUserRole>()。HasKey(r => new {r.RoleId,r.UserId}); //不要添加
//其他映射代码
}


I am using ASP.NET Identity 2.1.0 using Entity Framework implementation.
Authentication works fine but role based security has problem. Although I've added role to the user but this code returns empty :

  var roles= UserManager.GetRoles(User.Identity.GetUserId());

Also Authorization based on roles of logged in user fails. when user redirects to a controller like below application redirects him to the login page.

  [Authorize(Roles = "Admin")]
    public abstract partial class AdminAreaController : Controller
    {

In order to add ASP.NET Identity, first, I have created custom user class to add profile data :

    public class BasemapUser : IdentityUser
{
    [MaxLength(100)]
    public string Name { get; set; }

    [MaxLength(100)]
    public string CompanyName { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<BasemapUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        ClaimsIdentity userIdentity =
            await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

This is DbContext class :

    public class WebCoreMapDbContext : IdentityDbContext<BasemapUser>
{
    public WebDbContext()
        : base("WebDbContext")
    {
    }

    public static WebCoreMapDbContext Create()
    {
        return new WebCoreMapDbContext();
    }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
       modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId});
    }
}

I created database using EF Migration commands in power shell. I see two extra columns in IdentityUserRoles table which I haven't seen in other samples of ASP.NET identity

I used this code to add default admin user and role:

        public static void Start()
    {
        var userManager = HttpContext.Current.GetOwinContext().GetUserManager<BasemapUserManager>();
        var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
        const string name = "someEmail@gmail.com";
        const string password = "somePassword";
        const string roleName = "Admin";

        //Create Role Admin if it does not exist
        IdentityRole role = roleManager.FindByName(roleName);
        if (role == null)
        {
            role = new IdentityRole(roleName);
            IdentityResult roleresult = roleManager.Create(role);
        }

        BasemapUser user = userManager.FindByName(name);
        if (user == null)
        {
            user = new BasemapUser {UserName = name, Email = name};
            IdentityResult result = userManager.Create(user, password);
            result = userManager.SetLockoutEnabled(user.Id, false);
        }

        // Add user admin to Role Admin if not already added
        IList<string> rolesForUser = userManager.GetRoles(user.Id);
        if (!rolesForUser.Contains(role.Name))
        {
            IdentityResult result = userManager.AddToRole(user.Id, role.Name);

        }
    }

Admin user and role have been stored in database successfully but stored record in IdentityUserRoles table contains null value :

Why GetRoles returns nothing for the user who has that role in database? also other APIs like IsInRole doesn't work as expected. Is it because foreign keys which added to IdentityUserRoles table?

解决方案

The problem was unnecessary columns which have added to Identity tables.

Since DbContext extends from IdentityDbContext, I have to call base.OnModelCreating since the IdentityDbContext defines it for mapping Identity classes. I haven't called that in the my code which caused the issues

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
       modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId});
    }

Has to change to

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       base.OnModelCreating(modelBuilder);

      // modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);                // do not add this
      // modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId});         // do not add this
      // other mapping codes
    }

这篇关于授权和GetRoles在ASP.NET身份中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆