User.IsInRole()在角色分配后不起作用,但在重新登录后才起作用

11 c# asp.net-mvc owin asp.net-identity

在ASP.NET MVC 5应用程序中,我使用Unity容器来创建OWIN/Identity对象并解析所有依赖项.

问题是当我注册为新用户并为他分配这样的角色时

userManager.AddToRole(user.Id, "NewUser");
...
await userManager.UpdateAsync(user);
Run Code Online (Sandbox Code Playgroud)

它实际上在AspNetUserRoles表中创建了一条记录,但是在那之后如果我检查他的角色User.IsInRole("NewUser")我会变错,除非我退出然后再次登录,那么这是真的.

我想问题可能出在Unity上下文中的Identity对象(UserManager,RoleManager等)生命周期管理中.

UnityConfig.cs

public static void RegisterTypes(IUnityContainer container)
{
    // DbContext
    container.RegisterType<DbContext, AppEntitiesDbContext>();
    container.RegisterType<AppIdentityDbContext>();

    // Identity
    container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
                new InjectionConstructor(typeof(AppIdentityDbContext)));

    container.RegisterType<IAuthenticationManager>(
                new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));

    container.RegisterType<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>(
                new InjectionConstructor(typeof(AppIdentityDbContext)));

     container.RegisterType<ApplicationUserManager>();
     container.RegisterType<ApplicationSignInManager>();
     container.RegisterType<ApplicationRoleManager>();
}
Run Code Online (Sandbox Code Playgroud)

IdentityConfig.cs(我<add key="owin:AppStartup" value="MyApp.IdentityConfig" />在Web.config中使用)

public class IdentityConfig
{
    public void Configuration(IAppBuilder app)
    {
        var container = UnityConfig.GetConfiguredContainer();

        app.CreatePerOwinContext(() => container.Resolve<AppIdentityDbContext>());
        app.CreatePerOwinContext(() => container.Resolve<ApplicationUserManager>());
        app.CreatePerOwinContext(() => container.Resolve<ApplicationSignInManager>());
        app.CreatePerOwinContext(() => container.Resolve<ApplicationRoleManager>());

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login")
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Sho*_*hoe 6

这是因为使用User对象(IPrincipal)中的任何内容都会查看当前HTTP请求的用户身份标记,而不是用户的持久值.

当您登录时,该角色将从角色和其他声明中创建.如果更改用户在数据库中的角色,则需要重新创建令牌并将其设置为用户的新身份.

当您更改用户身份的一部分时.只需使旧令牌无效,然后通过签名将其重新签发,重新签发新令牌.

private async Task SignInAsync(User user, bool isPersistent)
    {
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
        var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
        AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
    }
Run Code Online (Sandbox Code Playgroud)