我有一个.netcore mvc应用程序,在其中我在CustomRoles类中具有角色:
public class CustomRoles
{
///<Summary>Manager role</Summary>
public const string Manager = "Manager";
///<Summary>Publisher role </Summary>
public const string Publisher = "Publisher";
}
在我的控制器中,我在端点上设置了Authorize:
/// <summary>
/// ASYNC Version: Get a List of Journals based on a Week Id
/// </summary>
/// <param name="weekId">Database unique Week ID</param>
/// <response code="204">No Content</response>
/// <response code="400">Bad Request</response>
/// <returns></returns>
[Authorize(Roles = CustomRoles.Manager +","+ CustomRoles.Publisher)]
[HttpGet("GetPartnerJounalsByIdAsync/")]
[ProducesResponseType(200, Type = typeof(JounalsPartnerGetResponse))]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
public async Task<ActionResult> GetPartnerJournalsByIdAsync([Required]int weekId)
{
//get from db
}
我想从数据库中填充角色,而不是在类中对其进行硬编码,因此我可以实现:
[Authorize (Roles = //Roles from the database)]
这是我创建的解决方案,但我遇到了麻烦。我实现了一个Role类:
public class Role
{
/////<Summary>Manager role</Summary>
public string RoleName { get; set; }
}
以及从数据库获取角色的方法:
/// <summary>
/// Get All Roles
/// </summary>
/// <returns></returns>
public async Task<List<Role>> GetRoles()
{
GetResponse response = new GetResponse();
List<Role> CRoles = new List<CustomRoles>();
response = await database.ObjectGetTypedListAsync<Role>("", "Role");
CRoles = (List<Role>)response.StronglyTypedObject;
return CRoles;
}
有什么想法可以实现这一目标吗?
答案 0 :(得分:1)
要基于数据库中的数据检查角色,可以像
那样实现自己的IAuthorizationFilter
[AttributeUsage(AttributeTargets.Class)]
public class MyAuthorize : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var dbContext = context.HttpContext.RequestServices.GetRequiredService<ApplicationDbContext>();
var roles = dbContext.Roles.ToList();
foreach (var role in roles)
{
if (!context.HttpContext.User.IsInRole(role.Name))
{
context.Result = new ForbidResult();
}
}
}
}
并像这样使用它:
[MyAuthorize]
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
答案 1 :(得分:0)
我曾经使用过类似爱德华的回答。现在,我只使用 AccountController 中的 Login 方法:
public class AppUser
{
public string DisplayName { get; set; }
[Required]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
[HttpPost, ValidateAntiForgeryToken]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl, AppUser model)
{
// if input parameters are valid…
if (ModelState.IsValid)
{
// attempt to authenticate
var user = _authService.Login(model.Username, model.Password);
if (user != null)
{
// if login was successful, create Claims for Username and DisplayName
var userClaims = new List<Claim>
{
new Claim("displayName", user.DisplayName),
new Claim(ClaimTypes.Name, user.Username)
};
// as well as all the permitted Roles
var permissions = (from p in _context.Permissions
where p.Username == user.Username
select p.Name);
foreach (var role in permissions){
userClaims.Add(new Claim(ClaimTypes.Role, role));
}
ClaimsIdentity identity = new ClaimsIdentity(userClaims, _authService.GetType().Name);
identity.Label = user.DisplayName;
// save the ClaimsIdentity in the authentication cookie
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(identity),
// the cookie will persist for 7 days
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddDays(7)
}
);
}
}
return View(model);
}
显然,您有自己的身份验证。 AppUser 是登录视图中使用的模型。 Cookie 身份验证是免费的 :-)
现在您的控制器只需在您的控制器方法上使用 [Authorize(Roles = "permission")]
,其中 permission
是上面查询中的 p.name
。