c# - MVC 6 组权限无法获取角色

标签 c# entity-framework asp.net-core asp.net-core-mvc

我正在转换 ASP.NET Identity 2.0: Implementing Group-Based Permissions Management到 ASP.NET Core ,一切都很好,但我无法从组中获得角色

代码如下:

应用组实体

public sealed class ApplicationGroup
{
    [Key]
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<ApplicationGroupRole> ApplicationGroupRoles { get; set; }
    public ICollection<ApplicationGroupUser> ApplicationGroupUsers { get; set; }

    public ApplicationGroup()
    {
        Id = Guid.NewGuid().ToString();
        ApplicationGroupRoles = new List<ApplicationGroupRole>();
        ApplicationGroupUsers = new List<ApplicationGroupUser>();
    }

}

ApplicationGroupRole 实体

public class ApplicationGroupRole
{
    public string ApplicationRoleId { get; set; }

    public string ApplicationGroupId { get; set; }
    [ForeignKey("ApplicationGroupId")]
    public ApplicationGroup ApplicationGroup { get; set; }

}

应用组用户实体

public class ApplicationGroupUser
{
    public string ApplicationUserId { get; set; }

    public string ApplicationGroupId { get; set; }
    [ForeignKey("ApplicationGroupId")]
    public ApplicationGroup ApplicationGroup { get; set; }

}

DbContext OnModelCreating :

        modelBuilder.Entity<ApplicationGroup>()
            .HasMany(u => u.ApplicationGroupUsers);

        modelBuilder.Entity<ApplicationGroupUser>()
            .HasKey(r => new {r.ApplicationUserId, r.ApplicationGroupId});

        modelBuilder.Entity<ApplicationGroup>()
            .HasMany(g => g.ApplicationGroupRoles);

        modelBuilder.Entity<ApplicationGroupRole>()
            .HasKey(gr => new { gr.ApplicationRoleId, gr.ApplicationGroupId});

        modelBuilder.Entity<ApplicationGroupUser>().ToTable("ApplicationUserGroups");

        modelBuilder.Entity<ApplicationGroupRole>().ToTable("ApplicationRoleGroups");

        modelBuilder.Entity<ApplicationGroup>().ToTable("ApplicationGroups");

Controller :

    public ActionResult Details(string id)
    {
        if (id == null)
        {
            return new StatusCodeResult(400);
        }
        ApplicationGroup applicationgroup = _groupManager.Groups.FirstOrDefault(g => g.Id == id);
        if (applicationgroup == null)
        {
            return new NotFoundResult();
        }
        var groupRoles = _groupManager.GetGroupRoles(applicationgroup.Id);
        var RoleNames = groupRoles.Select(p => p.Name).ToArray();
        ViewBag.RolesList = RoleNames;
        ViewBag.RolesCount = RoleNames.Count();
        return View(applicationgroup);
    }

查看:

@model ApplicationGroup

@{
    ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
    <h4>ApplicationGroup</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Name)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Name)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Description)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Description)
        </dd>
    </dl>
</div>
<h4>List of permissions granted this group</h4>
@if (ViewBag.PermissionsCount == 0)
{
    <hr />
    <p>No users found in this role.</p>
}
<table class="table">
    @foreach (var item in ViewBag.RolesList)
    {
        <tr>
            <td>
                @item
            </td>
        </tr>
    }
</table>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
    @Html.ActionLink("Back to List", "Index")
</p>

结果是当我到达 View 时,没有角色,请帮助解决这个问题,我哪里错了? Screen Shoot

解决方案更新:

需要将 Controller 更改为:

public ActionResult Details(string id)
{
    if (id == null)
    {
        return new StatusCodeResult(400);
    }
    var applicationgroup = _groupManager.Groups
            .Where(g => g.Id == id)
            .Select(g => new ApplicationGroup()
            {
                ApplicationGroupRoles = g.ApplicationGroupRoles
            }).FirstOrDefault();

    if (applicationgroup == null)
    {
        return new NotFoundResult();
    }
    var groupRoles = _groupManager.GetGroupRoles(applicationgroup.Id);
    var RoleNames = groupRoles.Select(p => p.Name).ToArray();
    ViewBag.RolesList = RoleNames;
    ViewBag.RolesCount = RoleNames.Count();
    return View(applicationgroup);
}

并且需要将其他类中的一些查询更改为:

            var grp = _db.ApplicationGroups
            .Where(y => y.Id == groupId)
            .Select(g => new ApplicationGroup()
            {
                ApplicationGroupRoles = g.ApplicationGroupRoles
            })
            .FirstOrDefault();

最佳答案

在身份 2 中,我做了类似于您引用的组权限项目的事情。除了我将它们命名为 Profiles 而不是 Groups 之外。我开始在 Identity Core 中做同样的事情,但后来意识到我可以使用一个名为 UserRoleClaim 的新身份表。使用这个新表,我完成了同样的事情,而无需修改 Identity Core 数据库架构。此外,我不必编写自己的 EF 代码。一切都可以通过 UserManagerRoleManager 类中的内置方法完成。

您现在可以将一个组等同于一个角色。每个角色可以有多个声明,多个用户可以属于一个角色。授权用户的关键是与用户所属角色相关的声明。您不能直接在授权属性中使用声明(那样会很困惑)。您必须将 claim 与保单相关联。 策略是 Identity Core 中的绝妙之处!它们使您可以将声明组织到配置文件中。然后您只需将配置文件添加到您的授权属性。这比在身份 2 中添加角色和/或声明列表要好得多。

配置文件是使用类 Startup 的 ConfigureServices() 方法中的 services.AddAuthorization() 方法创建的。

services.AddAuthorization(options =>
{
    options.AddPolicy("Product", policy => policy.RequireClaim("Product"));
    options.AddPolicy("ProductEdit", policy => policy.RequireClaim("Product", "Edit"));
});

您可以在授权属性中使用这些政策。

[Authorize(Policy = "Product")]
public class ProductController : Controller
{
    [HttpGet]
    public IActionResult Index()
    {
        return View();
    }

    [HttpGet]
    [Authorize(Policy = "ProductEdit")]
    public IActionResult Edit()
    {
        return View();
    }
}

在做出任何设计决定之前,我会阅读 Identity Core 中的授权。该文档实际上非常好并且易​​于阅读。我建议至少阅读这些文章。
Claims-Based Authorization
Policy-Based Authorization

我已经描述了 Identity Core 中声明和基于策略的授权的基础知识。但是按照我上面链接的文档中的其余文章,您会发现还有更多选项可供您使用。

关于c# - MVC 6 组权限无法获取角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38463870/

相关文章:

c# - Entity Framework : Map a Guid property in C# to a Database String

asp.net-mvc - 查看型号: Data Duplication VS Performance

linq - 如何创建一个必须满足两个值的谓词,其中一个是值列表?

c# - VS 代码 CSC : error CS1617: Invalid option '7.3' for/langversion

c# - C#中的波形分析

C# WPF 应用程序 .NET 4.5 设置鼠标位置

c# - 如果在foreach循环下动态生成Textarea不止一次,如何在Razor(blazor)组件中获取Textarea值

asp.net-core - 带有路由的 Razor Pages 局部 View

c# - 问题级联下拉列表,生成的下拉列表未将选定值发布到服务器

c# - 如何在不破坏现有 Object.Equals() 的情况下仅检查两个对象的属性是否相等?