การสร้างบทบาทใน Asp.net Identity MVC 5


85

เอกสารเกี่ยวกับการใช้ Asp.net Identity Security Framework ใหม่มีน้อยมาก

ฉันได้ปะติดปะต่อสิ่งที่ทำได้เพื่อลองสร้างบทบาทใหม่และเพิ่มผู้ใช้เข้าไป ฉันลองทำสิ่งต่อไปนี้: เพิ่มบทบาทใน ASP.NET Identity

ซึ่งดูเหมือนว่าอาจได้รับข้อมูลจากบล็อกนี้: การสร้างแอปพลิเคชันที่ต้องทำง่ายๆด้วยข้อมูลประจำตัว asp.net และเชื่อมโยงผู้ใช้กับสิ่งที่ต้องทำ

ฉันได้เพิ่มรหัสลงในตัวเริ่มต้นฐานข้อมูลที่ทำงานเมื่อใดก็ตามที่โมเดลมีการเปลี่ยนแปลง มันล้มเหลวในRoleExistsฟังก์ชันโดยมีข้อผิดพลาดต่อไปนี้:

System.InvalidOperationException เกิดขึ้นใน mscorlib.dll ชนิดเอนทิตี IdentityRole ไม่ได้เป็นส่วนหนึ่งของโมเดลสำหรับบริบทปัจจุบัน

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

ขอความช่วยเหลือใด ๆ

คำตอบ:


26

ตรวจสอบว่าคุณมีลายเซ็นของMyContextชั้นเรียนของคุณ

public class MyContext : IdentityDbContext<MyUser>

หรือ

public class MyContext : IdentityDbContext

รหัสใช้งานได้สำหรับฉันโดยไม่ต้องแก้ไขใด ๆ !!!


4
ขอบคุณทุกคนสำหรับการตอบกลับของคุณ ตอนนี้ทุกอย่างกำลังทำงาน การตรวจสอบบริบททำให้ฉันไปในทิศทางที่ถูกต้อง เมื่อสร้างเอกลักษณ์ของ asp.net จะสร้างบริบทใหม่ (ApplicationDbContext) ซึ่งขยาย IdentityDbContext ในรหัสของฉันฉันอ้างถึงบริบทเดิมของฉันซึ่งไม่ได้ขยาย IdentityDbContext หากมีคนอื่นมีปัญหานี้ให้ตรวจสอบบริบทของคุณและตรวจสอบไดเรกทอรี APP_DATA ของคุณอีกครั้งเพื่อให้แน่ใจว่าคุณไม่ได้สร้างฐานข้อมูลสองฐานข้อมูลโดยไม่ได้ตั้งใจ
colbyJax

74

ไปเลย:

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

    }

2
สิ่งนี้ช่วยฉันได้โดยเฉพาะอย่างยิ่งเมื่อฉันไม่ได้ใช้การย้ายข้อมูล ฉันใช้ DropCreateDatabaseAlways
J86

ปัญหาของฉันคือฉันใช้บริบทที่ไม่ถูกต้อง ฉันได้สร้างสตริงการเชื่อมต่อสองสายสายหนึ่งเรียกIdentityDbContextและอีกสายหนึ่งฉันใช้บริบทที่กำหนดเองดังนั้นเมื่อฉันใช้คำแนะนำของคุณAppilcationDbContext()มันก็ใช้ได้
megamaiku

var roleManager = RoleManager ใหม่ <IdentityRole> (RoleStore ใหม่ <IdentityRole> (db));
Nour Lababidi

25

นี่คือบทความฉบับสมบูรณ์ที่อธิบายวิธีสร้างบทบาทแก้ไขบทบาทลบบทบาทและจัดการบทบาทโดยใช้ ASP.NET Identity นอกจากนี้ยังมีส่วนต่อประสานผู้ใช้วิธีการควบคุม ฯลฯ

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

หวังว่านี่จะช่วยได้

ขอบคุณ


1
บล็อกของคุณดี แต่ล้าสมัยคุณสามารถอัปเดตตัวควบคุมบัญชีได้ไหม
aggie

มีแล้วสำหรับ ASP.NET MVC 5 (คุณกำลังมองหาอัปเดตอะไรบ้าง) คุณสามารถดาวน์โหลดซอร์สโค้ดได้จากลิงค์ GitHub ที่ระบุในบทความ
Sheo Narayan

1
ฟังก์ชั่นเหล่านี้บางส่วนดูเหมือนเลิกใช้งานจาก 2.2.0 ในเวอร์ชันล่าสุด 1) ฉันสามารถใช้รหัสเดียวกันในเวอร์ชันปัจจุบันได้อย่างไร 2) ฉันจะเปลี่ยนคีย์หลักจาก Guid เป็นอีเมลได้อย่างไร 3) คำแนะนำใด ๆ เกี่ยวกับวิธีการรวม recpatcha กับ Identity จะได้รับการชื่นชมj.mp/1nohaHe
aggie

15

ในASP.NET 5 rc1-finalฉันทำตาม:

สร้างขึ้นApplicationRoleManager(ในลักษณะเดียวกันกับที่ApplicationUserสร้างโดยเทมเพลต)

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

เพื่อConfigureServicesในStartup.csฉันเพิ่มเป็น RoleManager

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

สำหรับการสร้าง Roles ใหม่ให้เรียกจากสิ่งConfigureต่อไปนี้:

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

ตอนนี้สามารถกำหนดกฎให้กับผู้ใช้ได้

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

หรือใช้ในAuthorizeแอตทริบิวต์

[Authorize(Roles = "Developer")]
public class DeveloperController : Controller
{
}

services.AddIdentity<UserAuth, IdentityRole>().AddRoleManager<ApplicationRoleManager>() ฉันไม่สามารถเพิ่มเข้าไปservicesโดยตรง
Alex C

2
@AlexC ขออภัยฉันไม่ดี ฉันพยายามทำให้มันง่ายที่สุดและลบ AddIdentity แก้ไขแล้ว.
nothrow

1
ดังนั้นฉันจึงได้เพิ่มรหัสนั้นลงในโปรเจ็กต์แบบสแตนด์อโลนgithub.com/AlexChesser/AspnetIdentitySample/commit/…และ AspnetRoles สร้างได้สำเร็จ แต่ด้วยเหตุผลบางประการหน้าเว็บจะกลายเป็น 'สีขาว' (ฉันถือว่ามีข้อผิดพลาด 500 แต่ ไม่มี stacktrace) คุณสามารถแสดงผลเพจที่ติดตั้งไว้ได้หรือไม่?
Alex C

ตกลง - การกระทำนี้แก้ไขข้อผิดพลาดหน้าจอสีขาวgithub.com/AlexChesser/AspnetIdentitySample/commit/…โปรดสังเกตว่าภายใน SureRolesCreated ฉันได้เปลี่ยนเป็นโมฆะแทน Task
Alex C

1
การมีโมฆะคืนค่า 'SureRolesCreated' อาจหมายความว่าไม่ได้สร้างบทบาทก่อนที่การกำหนดค่าจะเสร็จสิ้น
ไม่ใช่

6

ในการปรับปรุงรหัส Peters ด้านบนคุณสามารถใช้สิ่งนี้:

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

   if (!roleManager.RoleExists("Member"))
            roleManager.Create(new IdentityRole("Member"));

3

แอปพลิเคชันของฉันหยุดทำงานเมื่อเริ่มต้นเมื่อฉันใช้ตัวอย่างโค้ดของ Peter Stulinski & Dave Gordon กับ EF 6.0 ฉันเปลี่ยน:

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

ถึง

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

ซึ่งสมเหตุสมผลเมื่ออยู่ในเมธอด seed คุณไม่ต้องการอินสแตนซ์อินสแตนซ์ของไฟล์ApplicationDBContext. สิ่งนี้อาจประกอบขึ้นด้วยความจริงที่ว่าฉันมีDatabase.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());ในตัวสร้างของApplicationDbContext


2

โมเดลมุมมองบทบาท

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

วิธีการควบคุม

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

1

ฉันต้องการแบ่งปันโซลูชันอื่นสำหรับการเพิ่มบทบาท:

<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" />
}

ตัวควบคุม:

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

1

หากคุณกำลังใช้เทมเพลตเริ่มต้นที่สร้างขึ้นเมื่อคุณเลือกแอปพลิเคชันเว็บ ASP.net ใหม่และเลือกบัญชีผู้ใช้ส่วนบุคคลเป็นการรับรองความถูกต้องและพยายามสร้างผู้ใช้ที่มีบทบาทดังนั้นนี่คือทางออก ในวิธีการลงทะเบียนควบคุมบัญชีซึ่งเรียกว่าใช้ [HttpPost] if conditionเพิ่มบรรทัดต่อไปนี้ใน

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

สิ่งนี้จะสร้างขึ้นก่อนสร้างบทบาทในฐานข้อมูลของคุณจากนั้นเพิ่มผู้ใช้ที่สร้างขึ้นใหม่ในบทบาทนี้



0

วิธีที่ฉันใช้ในการสร้างบทบาทอยู่ด้านล่างโดยกำหนดให้กับผู้ใช้ในโค้ดจะแสดงรายการด้วย โค้ดด้านล่างอยู่ใน "configuration.cs" ในโฟลเดอร์การย้ายข้อมูล

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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.