Tworzenie ról w Asp.net Identity MVC 5

85

Istnieje bardzo niewiele dokumentacji na temat korzystania z nowej platformy zabezpieczeń tożsamości Asp.net Identity Security.

Zebrałem wszystko, co mogłem, aby spróbować stworzyć nową rolę i dodać do niej użytkownika. Próbowałem wykonać następujące czynności: Dodaj rolę w ASP.NET Identity

który wygląda na to, że mógł uzyskać informacje z tego bloga: tworzenie prostej aplikacji do wykonania z tożsamością asp.net i kojarzenie użytkowników z zadaniami do wykonania

Dodałem kod do inicjatora bazy danych, który jest uruchamiany po każdej zmianie modelu. RoleExistsFunkcja kończy się niepowodzeniem z następującym błędem:

System.InvalidOperationException wystąpiło w mscorlib.dll Typ jednostki IdentityRole nie jest częścią modelu dla bieżącego kontekstu.

protected override void Seed (MyContext context)
{
    var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); 
    var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

    // Create Admin Role
    string roleName = "Admins";
    IdentityResult roleResult;

    // Check to see if Role Exists, if not create it
    if (!RoleManager.RoleExists(roleName))
    {
        roleResult = RoleManager.Create(new IdentityRole(roleName));
    }
}

Każda pomoc jest mile widziana.

colbyJax
źródło

Odpowiedzi:

26

Sprawdź, czy masz następujący podpis swojej MyContextklasy

public class MyContext : IdentityDbContext<MyUser>

Lub

public class MyContext : IdentityDbContext

Kod działa u mnie bez żadnych modyfikacji !!!

jd4u
źródło
4
Dzięki wszystkim za odpowiedzi. Teraz wszystko działa. Sprawdzenie kontekstu poprowadziło mnie w dobrym kierunku. Po utworzeniu tożsamości asp.net tworzy nowy kontekst (ApplicationDbContext), który rozszerza IdentityDbContext. W moim kodzie odwoływałem się do mojego oryginalnego kontekstu, który nie rozszerzał IdentityDbContext. Jeśli ktoś inny ma ten problem, sprawdź swoje konteksty i dwukrotnie sprawdź katalog APP_DATA, aby upewnić się, że nie tworzysz przypadkowo dwóch baz danych.
colbyJax
74

No to ruszamy:

var roleManager = new RoleManager<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));


   if(!roleManager.RoleExists("ROLE NAME"))
   {
      var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
      role.Name = "ROLE NAME";
      roleManager.Create(role);

    }
Piotr Stuliński
źródło
2
Pomogło mi to, zwłaszcza że nie korzystałem z migracji. Używam DropCreateDatabaseAlways.
J86
Mój problem polegał na tym, że użyłem niewłaściwego kontekstu. Stworzyłem dwa parametry połączenia, jeden wywołał, IdentityDbContexta drugi użyłem niestandardowego kontekstu, więc kiedy skorzystałem z twojej sugestii AppilcationDbContext(), zadziałało.
megamaiku
var roleManager = new RoleManager <IdentityRole> (new RoleStore <IdentityRole> (db));
Nour Lababidi
25

Oto pełny artykuł opisujący tworzenie ról, modyfikowanie ról, usuwanie ról i zarządzanie rolami przy użyciu ASP.NET Identity. Zawiera również interfejs użytkownika, metody kontrolera itp.

http://www.dotnetfunda.com/articles/show/2898/working-with-roles-in-aspnet-identity-for-mvc

Mam nadzieję, że to pomoże

Dzięki

Sheo Narayan
źródło
1
Twój blog jest fajny, ale nieaktualny, czy możesz zaktualizować kontroler konta
aggie
Jest już dla ASP.NET MVC 5 (jakiej aktualizacji szukasz aggie?). Możesz pobrać kod źródłowy z linku GitHub podanego w artykule.
Sheo Narayan
1
Niektóre z tych funkcji wydają się być przestarzałe w stosunku do wersji 2.2.0. 1) czy mogę użyć tego samego kodu w obecnej wersji 2) jak mogę zmienić klucz podstawowy z Guid na e-mail 3) wszelkie zalecenia dotyczące integracji recpatcha z tożsamością będą mile widziane j.mp/1nohaHe
aggie
15

W ASP.NET 5 rc1-final, wykonałem następujące czynności:

Utworzono ApplicationRoleManager(podobnie jak jest to ApplicationUsertworzone przez szablon)

public class ApplicationRoleManager : RoleManager<IdentityRole>
{
    public ApplicationRoleManager(
        IRoleStore<IdentityRole> store,
        IEnumerable<IRoleValidator<IdentityRole>> roleValidators,
        ILookupNormalizer keyNormalizer,
        IdentityErrorDescriber errors,
        ILogger<RoleManager<IdentityRole>> logger,
        IHttpContextAccessor contextAccessor)
        : base(store, roleValidators, keyNormalizer, errors, logger, contextAccessor)
    {
    }
}

Aby ConfigureServicesIN Startup.cs, dodałem go jako RoleManager

services.
    .AddIdentity<ApplicationUser, IdentityRole>()
    .AddRoleManager<ApplicationRoleManager>();

Aby utworzyć nowe role, zadzwoń z Configurenastępujących:

public static class RoleHelper
{
    private static async Task EnsureRoleCreated(RoleManager<IdentityRole> roleManager, string roleName)
    {
        if (!await roleManager.RoleExistsAsync(roleName))
        {
            await roleManager.CreateAsync(new IdentityRole(roleName));
        }
    }
    public static async Task EnsureRolesCreated(this RoleManager<IdentityRole> roleManager)
    {
        // add all roles, that should be in database, here
        await EnsureRoleCreated(roleManager, "Developer");
    }
}

public async void Configure(..., RoleManager<IdentityRole> roleManager, ...)
{
     ...
     await roleManager.EnsureRolesCreated();
     ...
}

Teraz reguły można przypisać do użytkownika

await _userManager.AddToRoleAsync(await _userManager.FindByIdAsync(User.GetUserId()), "Developer");

Lub używany w Authorizeatrybucie

[Authorize(Roles = "Developer")]
public class DeveloperController : Controller
{
}
nothrow
źródło
services.AddIdentity<UserAuth, IdentityRole>().AddRoleManager<ApplicationRoleManager>() Nie udało mi się dodać tego servicesbezpośrednio do .
Alex C,
2
@AlexC, Przepraszam, moja wina. Starałem się, aby było to tak proste, jak to tylko możliwe i usunąłem AddIdentity. Naprawiony.
nothrow
1
Więc dodałem ten kod do samodzielnego projektu github.com/AlexChesser/AspnetIdentitySample/commit/ ... i AspnetRoles zostały pomyślnie utworzone, ale z jakiegoś powodu strony stają się `` białymi ekranami '' (zakładam błąd 500, ale no stacktrace) czy byłeś w stanie renderować strony z tym zainstalowanym?
Alex C
ok - to zatwierdzenie naprawia błąd whitescreen github.com/AlexChesser/AspnetIdentitySample/commit/ ... zauważ, że w ramach GuaranteeRolesCreated przestawiłem go na void zamiast Task.
Alex C
1
zwracanie pustej wartości „GuaranteeRolesCreated” może oznaczać, że role nie zostaną utworzone przed zakończeniem konfiguracji
odtwórz
6

Jako ulepszenie powyższego kodu Peters możesz użyć tego:

   var roleManager = new RoleManager<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

   if (!roleManager.RoleExists("Member"))
            roleManager.Create(new IdentityRole("Member"));
Dave Gordon
źródło
3

Moja aplikacja zawieszała się na starcie, kiedy korzystałem z próbek kodu Petera Stulińskiego i Dave'a Gordona z EF 6.0. Zmieniłam:

var roleManager = new RoleManager<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

do

var roleManager = new RoleManager<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>(new RoleStore<IdentityRole>(**context**));

Ma to sens, gdy w metodzie początkowej nie chcesz tworzyć instancji kolejnej instancji ApplicationDBContext. Mogło to być spotęgowane przez fakt, że miałem Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());w konstruktorzeApplicationDbContext

Dane W.
źródło
2

Role Zobacz model

public class RoleViewModel
{
    public string Id { get; set; }
    [Required(AllowEmptyStrings = false)]
    [Display(Name = "RoleName")]
    public string Name { get; set; }
}

Metoda kontrolera

    [HttpPost]
    public async Task<ActionResult> Create(RoleViewModel roleViewModel)
    {
       if (ModelState.IsValid)
       {
           var role = new IdentityRole(roleViewModel.Name);
           var roleresult = await RoleManager.CreateAsync(role);
           if (!roleresult.Succeeded)
           {
               ModelState.AddModelError("", roleresult.Errors.First());
               return View();
           }
           return RedirectToAction("some_action");
       }
       return View();
    }
Moji
źródło
1

Chciałem udostępnić inne rozwiązanie do dodawania ról:

<h2>Create Role</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<span class="label label-primary">Role name:</span>
<p>
    @Html.TextBox("RoleName", null, new { @class = "form-control input-lg" })
</p>
<input type="submit" value="Save" class="btn btn-primary" />
}

Kontroler:

    [HttpGet]
    public ActionResult AdminView()
    {
        return View();
    }

    [HttpPost]
    public ActionResult AdminView(FormCollection collection)
    {
        var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

        if (roleManager.RoleExists(collection["RoleName"]) == false)
        {
            Guid guid = Guid.NewGuid();
            roleManager.Create(new IdentityRole() { Id = guid.ToString(), Name = collection["RoleName"] });
        }
        return View();
    }
JoshYates1980
źródło
1

Jeśli używasz domyślnego szablonu, który jest tworzony po wybraniu nowej aplikacji sieci Web ASP.net i wybraniu indywidualnych kont użytkowników jako uwierzytelniania i próbie utworzenia użytkowników z rolami, oto rozwiązanie. W metodzie Rejestr kontrolera konta, która jest wywoływana przy użyciu [HttpPost], dodaj następujące wiersze w if condition.

using Microsoft.AspNet.Identity.EntityFramework;

var user = new ApplicationUser { UserName = model.Email, Email = model.Email };

var result = await UserManager.CreateAsync(user, model.Password);

if (result.Succeeded)
{
  var roleStore = new RoleStore<IdentityRole>(new ApplicationDbContext());
  var roleManager = new RoleManager<IdentityRole>(roleStore);
  if(!await roleManager.RoleExistsAsync("YourRoleName"))
     await roleManager.CreateAsync(new IdentityRole("YourRoleName"));

  await UserManager.AddToRoleAsync(user.Id, "YourRoleName");
  await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
  return RedirectToAction("Index", "Home");
}

Spowoduje to utworzenie najpierw roli w bazie danych, a następnie dodania nowo utworzonego użytkownika do tej roli.

Hamza Khanzada
źródło
0
    public static void createUserRole(string roleName)
    {
        if (!System.Web.Security.Roles.RoleExists(roleName))
        {
            System.Web.Security.Roles.CreateRole(roleName);
        }
    }
Stephan Ahlf
źródło
0

metoda, której używam do tworzenia ról, znajduje się poniżej, podano również przypisywanie ich do użytkowników w kodzie. poniższy kod znajduje się w pliku „configuration.cs” w folderze migracji.

string [] roleNames = { "role1", "role2", "role3" };
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

                IdentityResult roleResult;
                foreach(var roleName in roleNames)
                {
                    if(!RoleManager.RoleExists(roleName))
                    {
                        roleResult = RoleManager.Create(new IdentityRole(roleName));
                    }
                }
                var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
                UserManager.AddToRole("user", "role1");
                UserManager.AddToRole("user", "role2");
                context.SaveChanges();
Kevin
źródło