我有一个带有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);
答案 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;