用户在角色和QUOT;管理"但[授权(角色="管理")将不进行身份验证 [英] User is in role "admin" but [Authorize(Roles="admin")] won't authenticate
问题描述
我发现SO描述一个伟大的答案<一个href=\"http://stackoverflow.com/questions/1822548/mvc-how-to-store-assign-roles-of-authenticated-users/1826413#1826413\">how设置自定义用户角色和我做我的项目是一样的。所以在我的登录服务,我有:
I found a great answer on SO describing how to set up custom user roles, and I've done the same in my project. So in my Login service I have:
public ActionResult Login() {
// password authentication stuff omitted here
var roles = GetRoles(user.Type); // returns a string e.g. "admin,user"
var authTicket = new FormsAuthenticationTicket(
1,
userName,
DateTime.Now,
DateTime.Now.AddMinutes(20), // expiry
false,
roles,
"/");
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(cookie);
return new XmlResult(xmlDoc); // don't worry so much about this - returns XML as ActionResult
}
而在Global.asax.cs中,我已经(从逐字对方回答复制):
And in Global.asax.cs, I have (copied verbatim from the other answer):
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
var authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null) {
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
var roles = authTicket.UserData.Split(new Char[] { ',' });
var userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
Context.User = userPrincipal;
}
}
然后,在我的 ServicesController
类,我有:
[Authorize(Roles = "admin")]
//[Authorize]
public ActionResult DoAdminStuff() {
...
}
我登录与管理员角色的用户,以及工程。然后,我打电话/服务/ doadminstuff - 我得到拒绝访问,即使当我把在Global.asax.cs中断点,我可以看到我的角色确实包括管理员。如果我注释掉的第一个授权
属性(角色),只需使用一个普通的授权
,那么我可以访问该服务。
I login as a user with the "admin" role, and that works. Then I call /services/doadminstuff - and I get access denied, even though when I put a breakpoint in Global.asax.cs, I can see that my roles do include "admin". If I comment out the first Authorize
attribute (with roles) and just use a plain vanilla Authorize
, then I can access the service.
我必须在这里失去了一些东西的关键 - 但哪里开始寻找
I must be missing something critical here - but where to start looking?
推荐答案
我会建议你使用自定义授权属性,而不是 Application_AuthenticateRequest
:
I would recommend you use a custom authorize attribute instead of Application_AuthenticateRequest
:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
string cookieName = FormsAuthentication.FormsCookieName;
if (!filterContext.HttpContext.User.Identity.IsAuthenticated ||
filterContext.HttpContext.Request.Cookies == null ||
filterContext.HttpContext.Request.Cookies[cookieName] == null
)
{
HandleUnauthorizedRequest(filterContext);
return;
}
var authCookie = filterContext.HttpContext.Request.Cookies[cookieName];
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = authTicket.UserData.Split(',');
var userIdentity = new GenericIdentity(authTicket.Name);
var userPrincipal = new GenericPrincipal(userIdentity, roles);
filterContext.HttpContext.User = userPrincipal;
base.OnAuthorization(filterContext);
}
}
和则:
[CustomAuthorize(Roles = "admin")]
public ActionResult DoAdminStuff()
{
...
}
另外一个很重要的事情是要确保当您登录,因为你返回的XML文件验证cookie被发送。使用Firebug检查身份验证Cookie是否正常发送当您尝试访问该网址 /服务/ doadminstuff
。
这篇关于用户在角色和QUOT;管理&QUOT;但[授权(角色=&QUOT;管理&QUOT;)将不进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!