Identity 2.0中的自定义表名称,User.IsInRole()无效

时间:2014-09-14 19:00:58

标签: asp.net-mvc-5 entity-framework-6 asp.net-identity

我尝试使用以下代码重命名表:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<IdentityUser>().ToTable("Users").Property(p => p.Id).HasColumnName("UserId");
    modelBuilder.Entity<ApplicationUser>().ToTable("Users").Property(p => p.Id).HasColumnName("UserId");
    modelBuilder.Entity<IdentityRole>().ToTable("Roles");
    modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles");
    modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogins");
    modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaims");
}

有效。表名已正确重命名,数据似乎插入到适当的位置。

但是,User.IsInRole("rolestring")方法不起作用。它始终返回false 如果我删除上面的代码,一切正常 我错过了什么?

更新
Here's the database content, just in case it helps

1 个答案:

答案 0 :(得分:0)

在Startup类中,在配置OAuthAuthorizationServerOptions时,在Provider属性上,您应该有一个继承自OAuthAuthorizationServerProvider的自定义类。在下面的示例中, CustomAuthorizationServerProvider 类:

OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions
{
    AllowInsecureHttp = true,
    TokenEndpointPath = new PathString("/token"),
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
    Provider = new CustomAuthorizationServerProvider()
};

这是CustomAuthorizationServerProvider的代码,您必须覆盖 GrantResourceOwnerCredentials

public class CustomAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        ...
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");

        if (allowedOrigin == null) allowedOrigin = "*";

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

        IdentityUser user;
        using (AuthRepository repository = new AuthRepository())
        {
            user = await repository.FindUser(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect");
                return;
            }
        }

        UserManager<IdentityUser> userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(new AuthDBContext()));
        ClaimsIdentity identity = await userManager.CreateIdentityAsync(user, context.Options.AuthenticationType);

        AuthenticationProperties properties = new AuthenticationProperties(new Dictionary<string, string>
        {
            {
                "as:client_id", context.ClientId ?? string.Empty
            },
            {
                "userName", context.UserName
            },
            {
                "roles",String.Join(",", (IEnumerable<IdentityUserRole>) user.Roles.ToArray())
            }
        });

        AuthenticationTicket ticket = new AuthenticationTicket(identity, properties);
        context.Validated(ticket);
    }

    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
        {
            context.AdditionalResponseParameters.Add(property.Key, property.Value);
        }

        return Task.FromResult<object>(null);
    }
}

注意:AuthDBContext与您声明 OnModelCreating 方法的类相同。

因此,回顾上面的代码,您将检查用户角色是否已插入AuthenticationProperties字典中

{
    "roles",String.Join(",", (IEnumerable<IdentityUserRole>) user.Roles.ToArray())
}

然后将它们插入到当前用户的ClaimsIdentity对象的票证中。

AuthenticationTicket ticket = new AuthenticationTicket(identity, properties);

修复此问题后,您只需在操作和/或控制器中添加[授权]属性,如下所示:

[Authorize(Roles = "Admin")]

或者检查控制器操作中的等效内容:

ActionContext.RequestContext.Principal.IsInRole("Admin")