8

全局 asax 中的HttpContext.Current.User与操作方法中的HttpContext.User不同吗?我为用户分配了一些角色,但他们似乎迷路了。

下面的代码显示了正在发生的事情。当用户登录时,这两个断言都会被命中,首先是全局 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

4

1 回答 1

8

您的问题标签上写着“aspnet-mvc (3 and 4)”,那么您是否可以选择使用以下内容让您的生活更轻松?如果您在 VS2012 中使用MVC 4 Internet 应用程序模板中的Simple Membership,这将为您开箱即用):

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属性等价的原始问题。

HttpContext在 Controller 中是一个属性:Controller.HttpContext. HttpContextglobal.asax.cs 中是静态类,所以这就是你使用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;
}

问题是,您分配了一个GenericPrincipalto .User。根据RoleProvider,这可以在RoleManagerModule期间被覆盖(例如被 )PostAuthenticateRequest和(例如)变成RolePrincipal。然后,这可以推迟回数据库(再次取决于提供者)来获取角色,因此覆盖您的角色。如果你在里面工作,Application_OnPostAuthenticateRequest你可能会没事的。

于 2013-05-22T13:58:28.970 回答