2014-10-20 2 views
2

Я использую ASP.NET Identity 2.1.0 с использованием реализации Entity Framework.
Аутентификация работает нормально, но на основе ролевой безопасности есть проблема. Хотя я добавил роль для пользователя, но этот код возвращает пустой:Авторизовать и GetRoles не работает в ASP.NET Identity

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

Кроме авторизации на основе ролей вошедшего пользователя не удается. когда пользователь перенаправляет на контроллер, такой как приложение ниже, перенаправляет его на страницу входа.

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

Для того, чтобы добавить ASP.NET идентичности, во-первых, я создал пользовательский класс пользователей для добавления данных профиля:

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

Это DbContext класс:

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

я создал используя команды EF Migration в оболочке питания. Я вижу две дополнительные колонки в таблице IdentityUserRoles, которые я не видел в других образцах идентичности ASP.NET

Extra columns in IdentityUserRoles

Я использовал этот код для добавления пользователя с правами администратора по умолчанию и роли:

 public static void Start() 
    { 
     var userManager = HttpContext.Current.GetOwinContext().GetUserManager<BasemapUserManager>(); 
     var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>(); 
     const string name = "[email protected]"; 
     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); 

     } 
    } 

пользователь администратора и роль были сохранены в базе данных успешно, но хранится запись в IdentityUserRoles таблицы содержит пустое значение:

Null value

Почему GetRoles ничего не возвращает пользователю, который имеет эту роль в базе данных? также другие API, такие как IsInRole, не работают должным образом. Это связано с тем, что внешние ключи, добавленные в таблицу IdentityUserRoles?

+0

Что 'BasemapUser.GenerateUserIdentityAsync' возвращается? Что возвращает объект 'ClaimsIdentity' в свойстве' .Claims'? – trailmax

+0

@trailmax Я не использовал это вообще. Это просто взято из образцов ASP.NET Identity в Nuget. – Shahin

+0

Не уверен, что делает образец - не смотрел на него какое-то время. Но похоже, что «ClaimsPrincipal», который вы получаете из фреймворка, не имеет ролей в качестве приложенных требований (он должен). В контроллере входа в систему попробуйте добавить этот код и посмотреть, есть ли на нем сгенерированный список «Claims». – trailmax

ответ

4

Проблема была в ненужных столбцах, которые добавлены в таблицы Identity.

Поскольку DbContext распространяется из IdentityDbContext, я должен вызвать base.OnModelCreating, поскольку IdentityDbContext определяет его для сопоставления классов Identity. Я не назвал, что в моем коде, который вызвал проблемы

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);    // do not add this 
     // modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId});   // do not add this 
     // other mapping codes 
    } 
+1

Спасибо большое shaahin, его решена моя проблема после долгой борьбы. и я поделился своими комментариями здесь, потому что, если кто-то столкнулся с этой же проблемой, это решение, безусловно, будет работать. –

Смежные вопросы