ASP.NET.MVC 5将权限添加到控制器的操作

时间:2018-07-20 08:05:44

标签: c# asp.net asp.net-mvc asp.net-mvc-5

我有一个带有Windows身份验证的项目,并且有一个控制器,我有一个问题,通过下面的控制器,我可以通过指定分支的名称(例如,在浏览器地址栏中输入URL)来获取信息:

http://localhost:62249/Students/TestNew/Branch1”;

它将显示给用户数据,其中branch = Branch1。

现在的问题是-如何实现以下目标?

对于每个分支名称,我希望通过从ActiveDirectory中指定组来指定允许打开此页面的权限。还是不可能,我应该再创建10个控制器,并为每个控制器指定权限。

    [HttpGet]
    public ActionResult TestNew(string branchname)
    {
        // check stuff like permissions
        var db = new MovieContext();
        var model = new Model();


        var students = db.Student
            .Where(x => x.BranchName == branchname)
            .GroupBy(x => new { x.BranchName, x.Name, x.Currency, x.NoCart, x.NoAccount })
            .Select(x => new
            {
                BranchName = x.FirstOrDefault().BranchName,
                Name = x.FirstOrDefault().Name,
                A_Status = x.Max(p => p.A_Status),
                Currency = x.FirstOrDefault().Currency,
                NoCart = x.FirstOrDefault().NoCart,
                NoAccount = x.FirstOrDefault().NoAccount
            }).ToList();
        foreach (var item in students)
        {
            model.Students.Add(new Student
            {
                A_Status = item.A_Status,
                BranchName = item.BranchName,
                Name = item.Name,
                NoAccount = item.NoAccount,
                NoCart = item.NoCart,
                Currency = item.Currency

            });
        }
        return View(model);

1 个答案:

答案 0 :(得分:2)

您可以使用基于策略的授权https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.1,并在foreach循环中使用授权处理程序来检查是否允许当前用户访问资源。

这是我所做的一个示例,除了我在数据库中使用组而不是在AD组中:

首先,您需要创建一个需求,该需求可以是空的,也可以是空的,具体取决于您的需求,因为在Microsoft文档中,它可以包含您的组名。

 public class CIAssetManagementRequirement : IAuthorizationRequirement
{
}

然后您的Policy,该类的目的是返回context.Succeed(requirement);当允许用户执行操作时:

 public class CIAuthoringManagement : AuthorizationHandler<CIAuthoringManagementRequirement, ConfigurationItem>
{
    private readonly MyAppContext _context;

    public CIAuthoringManagement(MyAppContext context)
    {
        _context = context;
    }

    [DebuggerStepThrough]
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CIAuthoringManagementRequirement requirement, ConfigurationItem resource)
    {
        var user = _context.Users.Include(u => u.Groups).Include(u => u.Employer).Include(c => c.AuthoringCatalogs).AsNoTracking().SingleOrDefault(m => m.ID == context.User.GetUniqueIdentifier());

        if (user != null)
        {
            //Allowing SuperAdmins by default
            var group = _context.Groups.Include(g => g.Users).ThenInclude(g => g.User).AsNoTracking().SingleOrDefault(g => g.DisplayName == "SuperAdmins");
            if (group != null)
            {
                var groupUsers = new HashSet<Guid>(group.Users.Select(u => u.User.ID));
                if (groupUsers.Contains(user.ID))
                {
                    context.Succeed(requirement);
                }
            }

            //Allowing CI if it's part of the catalogs where CI is author
            //hashset of id where user is declared author
            var authorCatalogHS = new HashSet<Guid>(user.AuthoringCatalogs.Select(c => c.CatalogId));

            if (resource.Catalogs != null)
            {
                foreach (var catalog in resource.Catalogs)
                {
                    if (authorCatalogHS.Contains(catalog.CatalogId))
                    {
                        context.Succeed(requirement);
                    }
                }
            }
            else
                context.Succeed(requirement);

        }

        return Task.CompletedTask;
    }
}

您可以在启动时实例化政策:

services.AddAuthorization(options =>
        {
            // require user to have cookie auth or jwt bearer token
            options.AddPolicy("Authenticated",
                policy => policy
                    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser());
                              options.AddPolicy("CIAuthoringManagement",
                policy => policy.Requirements.Add(new CIAuthoringManagementRequirement()));

                       });
services.AddTransient<IAuthorizationHandler, CIAuthoringManagement>();

最后在您的控制器中:

foreach (var ciApplication in _context.CIApplications.AsNoTracking())
                    {
                        if ((await _authorizationService.AuthorizeAsync(User, ciApplication, "CIAuthoringManagement")).Succeeded)
                        {

                            CIApplications.Add(ciApplication);
                        }
                    }
return CIApplications;