如何在 asp.net MVC 3 中实现基于角色的自定义用户身份验证。假设我有两个表 UserInfo(UserId, UserName, Password,RoleId)
和 Role(RoleId, RoleName) )
。
我想从数据库(UserInfo
表)验证用户,并且还想从该表中检索角色。并想使用像
[授权(Roles="Admin")]
需要您的帮助和想法......
最佳答案
您可以使用自定义授权属性并将角色存储在身份验证 cookie 的用户数据部分中。例如,在您的 LogOn 方法中,一旦您验证了凭据,您就可以从数据库中检索给定用户的角色并将其存储到用户数据中:
// TODO: fetch roles from your database based on the username
var roles = "Admin|SomeRole";
var ticket = new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddMilliseconds(FormsAuthentication.Timeout.TotalMilliseconds),
false,
roles
);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
Domain = FormsAuthentication.CookieDomain,
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL,
};
// Emit the authentication cookie which in addition to the username will
// contain the roles in the user data part
Response.AppendCookie(authCookie);
然后您可以编写一个自定义授权属性,该属性将用于读取身份验证 cookie 并提取角色信息:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.User.Identity.IsAuthenticated)
{
var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
var identity = new GenericIdentity(httpContext.User.Identity.Name);
var roles = (ticket.UserData ?? string.Empty).Split('|');
httpContext.User = new GenericPrincipal(identity, roles);
}
}
return base.AuthorizeCore(httpContext);
}
}
现在剩下的就是用这个新属性来装饰你的 Controller / Action :
[MyAuthorize(Roles = "Admin")]
public ActionResult Foo()
{
...
}
<小时/>
更新:
根据评论部分的要求,您可以在自定义授权属性中重写 HandleUnauthorizedRequest
方法,这样,如果用户无权访问给定操作,他就会被重定向到某个错误 View 登录页面:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Shared/Unauthorized.cshtml"
};
}
关于asp.net-mvc-3 - 如何在 asp.net MVC 3 中实现/创建基于角色的自定义用户身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7297788/