问题摘要:在ASP.NET MVC中,是否有一种干净的方法可以阻止特定用户或角色访问某个操作?
显然,以下内容允许角色Admin
和Editor
访问整个控制器。
[Authorize(Roles = "Admin, Editor")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
如果我只希望Admin
角色可以访问About
操作,我可以执行以下操作:
[Authorize(Roles = "Admin, Editor")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[Authorize(Roles = "Admin")] // this will take precedence over the controller's authorization
public ActionResult About()
{
return View();
}
}
有没有办法在不列出需要访问权限的每个角色的情况下完成此操作,并且只指定应该阻止访问的角色?
答案 0 :(得分:1)
以下是我用来解决此问题的类的代码。它源自public override async Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser) { var userIdentity = await CreateUserIdentityAsync(user); // your code here userIdentity.AddClaim(new Claim(ClaimTypes.Gender, "male")); // AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie); if (rememberBrowser) { var rememberBrowserIdentpublic override async Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser)
{
var userIdentity = await CreateUserIdentityAsync(user);
// your code here
userIdentity.AddClaim(new Claim(ClaimTypes.Gender, "male"));
//
uthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie);
if (rememberBrowser)
{
var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id));
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity, rememberBrowserIdentity);
}
else
{
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity);
}
}
,并且允许任何经过身份验证的用户通过不匹配参数设置的规范。
(请注意,重要的方法是AuthorizeAttribute
- 其他所有内容基本上都是从AuthorizeCore
复制或继承的)
AuthorizeAttribute
您可以在控制器或其他[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class BlackListAttribute : AuthorizeAttribute
{
private static readonly string[] _emptyArray = new string[0];
private string _roles;
private string _users;
private string[] _rolesSplit = _emptyArray;
private string[] _usersSplit = _emptyArray;
public new string Roles
{
get { return _roles ?? String.Empty; }
set
{
_roles = value;
_rolesSplit = SplitString(value);
}
}
public new string Users
{
get { return _users ?? String.Empty; }
set
{
_users = value;
_usersSplit = SplitString(value);
}
}
// This is the important part. Everything else is either inherited from AuthorizeAttribute or, in the case of private or internal members, copied from AuthorizeAttribute.
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
{
return false;
}
if (_usersSplit.Length > 0 && _usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if (_rolesSplit.Length > 0 && _rolesSplit.Any(user.IsInRole))
{
return false;
}
return true;
}
internal static string[] SplitString(string original)
{
if (String.IsNullOrEmpty(original))
{
return _emptyArray;
}
var split = from piece in original.Split(',')
let trimmed = piece.Trim()
where !String.IsNullOrEmpty(trimmed)
select trimmed;
return split.ToArray();
}
}
上的操作中使用它:
AuthorizeAttribute
答案 1 :(得分:1)
创建您自己的黑名单类,就像这样:
public class Blacklist : AuthorizeAttribute {
private List<string> RolesList;
public string Roles {
get {
string roles = "";
if (RolesList!= null && RolesList.Count > 0) {
int counter = 0;
foreach (string role in RolesList) {
counter++;
if (counter == RolesList.Count)
roles = role;
else
roles += role + ",";
}
}
return roles;
}
set {
RolesList = new List<string>();
string[] roles = value.Split(',');
foreach (string role in roles) {
RolesList.Add(role);
}
}
}
//constructor
public Blacklist () {
RolesList = new List<string>();
}
protected override bool AuthorizeCore(HttpContextBase httpContext) {
bool result = true;
if (httpContext == null) {
throw new ArgumentNullException("httpContext");
}
foreach (string role in RolesList) {
if (httpContext.User.IsInRole(role)) {
result = false;
break;
}
}
return result;
}
}
现在你将阻止你想要的角色:
[Authorize]
[Blacklist (Roles = "Admin", "Editor")]
public ActionResult Index() {
return View();
}