下面的代码显示了正在发生的事情.当用户登录时,两个Assert都会被点击,首先是全局的asax,然后是action方法.但是他们给出了不同的结果
首先这个:
protected void Application_AuthenticateRequest(object sender,EventArgs e) { // ... omitted some code to check user is authenticated FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity; string[] roles = new string[] { "admin","user" }; HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(identity,roles); Assert(HttpContext.User.IsInRole("admin")); }
然后在我的动作方法中:
public ActionResult Index() { bool isAdmin = HttpContext.User.IsInRole("admin"); Assert(isAdmin); // this fails,isAdmin is false // ... }
我使用了以下资源
http://csharpdotnetfreak.blogspot.com/2009/02/formsauthentication-ticket-roles-aspnet.html
解决方法
> WebSecurity.CreateUserAndAccount(name,password)
– 创建用户
> Roles.AddUserToRole
(和AddUserToRoles
) – 将用户添加到角色
> Roles.IsUserInRole
– 测试用户是否在角色中
> [Authorize(Roles = "admin")]
– [授权]可以在整个控制器或操作上强制执行角色
CreateUserAndAccount的优点是也可以轻松设置UserProfile的属性,例如:
WebSecurity.CreateUserAndAccount(newUser.UserName,newUser.Password,new { FullName = newUser.FullName,Email = newUser.Email,Timezone = newUser.TZ }); Roles.AddUserToRoles(newUser.UserName,new[] {"admin","user"});
编辑,我意识到上面没有回答你关于.User属性等价的原始问题.
Controller中的HttpContext是一个属性:Controller.HttpContext
.global.asax.cs中的HttpContext是静态类,这就是你使用HttpContext.Current的原因.他们指的是同一件事.
如果您运行以下代码,您可以看到它们显然是“相同的主体”.那么问题是你分配的角色发生了什么?
protected void Application_AuthenticateRequest(object sender,EventArgs e) { ... FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity; string[] roles = new string[] { "admin","user" }; identity.Label = "test label"; System.Security.Principal.GenericPrincipal ppl = new System.Security.Principal.GenericPrincipal(identity,roles); HttpContext.Current.User = ppl; ... } public ActionResult Index() { bool isAdmin = HttpContext.User.IsInRole("admin"); bool isAdmin2 = System.Web.HttpContext.Current.User.IsInRole("admin"); System.Web.Security.FormsIdentity identity = (System.Web.Security.FormsIdentity)HttpContext.User.Identity; // The label is carried through from Application_AuthenticateRequest to Index. string label = identity.Label; }
问题是,您为.User分配了GenericPrincipal.根据RoleProvider,可以在PostAuthenticateRequest期间覆盖(例如,通过RoleManagerModule),并且(例如)将其转换为RolePrincipal.然后,这可以推迟回到数据库(再次取决于提供者)以获取角色,从而覆盖您的角色.如果您在Application_OnPostAuthenticateRequest中完成工作,那么您可能没问题.