我希望在我的网站中实施基于角色的操作限制。例如,我希望限制仅由帖子作者或一组组编辑帖子的能力。
我知道我可以写下这样的内容:
if (User.IsInRole("Admin"))
return true;
return post.Author.AccountId == currentAccountId;
但我想知道的是,如果我可以动态地执行它而不使用固定的角色名称。我希望创建一个控制面板,使管理员能够添加新角色。在每个角色创建/修改表单中,都有一个复选框,上面写着“可以编辑其他帖子吗?”。基于该值,我将采取上述方法中的操作。我已经在PHP中完成了很多次,但是因为它是我的第一个ASP.NET MVC站点,我想知道是否可以使用默认的SQL数据库结构(使用MVC4和新的SimpleMembershipProvider,但我不介意写一个自定义提供者(如果必须)。
我已经阅读了有关新声明功能的内容,但在这种情况下我没有看到可以使用它的方式,我是对的吗?
我看了网但没找到任何东西......
非常欢迎任何建议!谢谢!
答案 0 :(得分:3)
是的,您可以使用表单身份验证进行一些自定义自动化,但您需要进行一些自定义。
首先,您必须自定义应用程序的AuthenticateRequest
事件以使用角色,因此,在Global.asax
上,您必须设置代码以将其自定义为当前用户:< / p>
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
if (HttpContext.Current.User.Identity.IsAuthenticated)
if (HttpContext.Current.User.Identity is FormsIdentity)
{
var id = (FormsIdentity)HttpContext.Current.User.Identity;
var ticket = id.Ticket;
// Get the stored user-data, in this case, our roles
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
当您对用户进行身份验证时,您必须设置角色,因此在您的控制器上,您必须使用以下代码进行身份验证后发布操作:
if (LoginService.Validate(userame, password)
{
FormsAuthentication.Initialize();
var ticket = new FormsAuthenticationTicket(1,
username, //user
DateTime.Now, //begin
DateTime.Now.AddHours(3), //timeout
false, //remember?
permission, // permission.. "admin" or for more than one "admin,marketing,sales"
FormsAuthentication.FormsCookiePath);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
HttpContext.Current.Response.Cookies.Add(cookie);
}
之后,您将能够使用类似帖子的代码:
if (User.IsInRole("Admin"))
{ /** do something / }
或者
if (User.IsInRole("Admin") || (User.IsInRole("Marketing") && User.IsInRole("Sales")))
{ /** do something / }
您还可以检查asp.net mvc的Authorize
属性上的角色:
[Authorize(Roles = "Admin")]
public class CompanyController : Controller
{
// actions
}
您可以拥有一个表,将权限“Admin”与某些权限相关联(编辑注释,删除注释等......可以存储在数据库的表中)。尝试这样的方法来实现自定义检查权限:
public static class UserExtension
{
private static bool RoleHasPrivilege(string role, int privilege)
{
// performe a database/cache access to check if the role has the privilege
}
public static bool IsInRole(this IPrincipal user, string role, int privilege)
{
// check if the user authenticate has the "role" permission and the privilege is associate with this role...
return user.IsInRole(role) && RoleHasPrivilege(role, privilege);
}
}
你可以使用:
if (User.IsInRole("Admin", 1))
{
// "Admins" has access
// 1 - can edit posts... for sample
}
答案 1 :(得分:0)
Felipe Oriani建议的解决方案不起作用
在global.asax中实现并使用方法
User.IsInRole( “管理员”)
它总是返回false。所以我想出了另一个在自定义AuthorizeAttribute中实现的解决方案。
public class AuthenticateRequestAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
HttpContextBase context = httpContext;
if (context.User != null)
if (context.User.Identity.IsAuthenticated)
if (context.User.Identity is FormsIdentity)
{
FormsIdentity id = (FormsIdentity)context.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
context.User = new GenericPrincipal(id, roles);
}
return base.AuthorizeCore(httpContext);
}
}
您可以使用此自定义属性代替内置的[授权]属性
[AuthenticateRequest]
public class AuthorizedController: Controller
{
}
然后你绝对可以使用
if (User.IsInRole("Admin"))
{ /** do something / }
希望这有帮助