C# ASP.NET标识-简化

C# ASP.NET标识-简化,c#,asp.net,asp.net-core,authorization,asp.net-identity,C#,Asp.net,Asp.net Core,Authorization,Asp.net Identity,现有数据库模型(简化): 1个用户可以加入1个或多个访问组 1访问组可以有1个或多个访问项 创建标识时,可以为其分配一个或多个由受信任方发布的声明。声明是一个名称-值对,表示主题是什么,而不是主题可以做什么 将AccessItems存储为UserClaims似乎不是一个好主意 e、 g: UserClaims->Name=CanDeleteSale;值=真 但另一方面,我想不出另一种方法 在进行了大量搜索之后,我无法思考如何使用ASP.NET标识中的角色或声明来表示此模型 为什么?

现有数据库模型(简化):

  • 1个用户可以加入1个或多个访问组
  • 1访问组可以有1个或多个访问项

创建标识时,可以为其分配一个或多个由受信任方发布的声明。声明是一个名称-值对,表示主题是什么,而不是主题可以做什么

将AccessItems存储为UserClaims似乎不是一个好主意

e、 g:

  • UserClaims->Name=CanDeleteSale;值=真
但另一方面,我想不出另一种方法

在进行了大量搜索之后,我无法思考如何使用ASP.NET标识中的角色或声明来表示此模型

为什么?

  • 管理员用户可以自定义访问组,然后使用声明性角色不适合这种情况

  • 我只能信任访问项,因为它们与枚举一样是固定Id,所以我希望使用声明性auth来使用枚举

  • 我需要在用户登录后存储所有用户AccessItems,并使用声明方式将其用于后期的身份验证操作

ASP.NET身份对我来说似乎很美,我现在正试图更好地理解它


对不起,如果我不能清楚地表达我的问题,请告诉我任何疑问。

我认为你的思路是正确的。我有很多这样的用户角色表示经验,我个人的偏好(我主要处理大型企业项目)是使用ASP.NET身份验证和使用自定义代码处理访问控制

对于较小的项目,我相信您可以像下面所做的那样定制IsUserInRole方法

public class CustomRoleProvider : RoleProvider
{
    /// <summary>
    /// Gets a list of roles assigned to a particular User
    /// </summary>
    /// <param name="UserID">ID of the User</param>
    /// <param name="context">DbContext</param>
    /// <returns></returns>
    public static List<string> GetUserRoles(int UserID, UserContext context)
    {
        return context.UserList
                      .Where(s => s.UserID == UserID)
                      .SelectMany(s => s.AccessGroup.GroupRoles)
                      .Select(gr => gr.RoleID.ToString()).ToList();
    }

    /// <summary>
    /// Gets a list of roles assigned to a particular user
    /// </summary>
    /// <param name="username">username of the user [or "" for current user]</param>
    /// <param name="context">DbContext</param>
    /// <returns></returns>
    public static List<string> GetUserRoles(string username, UserContext context)
    {
        return context.UserList
                      .Where(s => s.Username == username)
                      .SelectMany(s => s.AccessGroup.GroupRoles)
                      .Select(gr => gr.RoleID.ToString()).ToList();
    }

    //roleName = RoleId; so that only the IDs are stored in session...
    public override bool IsUserInRole(string username, string roleName)
    {
        return GetUserRoles(username, new UserContext()).Contains<string>(roleName);
    }

    public override string[] GetRolesForUser(string username)
    {
        return GetUserRoles(username, new UserContext()).ToArray();
    }

    public override string[] GetAllRoles()
    {
        return new UserContext().UserRoleList.Select(r => r.RoleID.ToString()).ToArray();
    }

    public override bool RoleExists(string roleName)
    {
        return new UserContext().UserRoleList.Where(r => r.RoleID.ToString().Equals(roleName)).Count() > 0;
    }

    public override string ApplicationName
    {
        get { return "Your Application Name"; }
        set { }
    }

    public override string[] GetUsersInRole(string roleName)
    {
        throw new System.NotImplementedException();
    }

    public override string[] FindUsersInRole(string roleName, string usernameToMatch)
    {
        throw new System.NotImplementedException();
    }

    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        throw new System.NotImplementedException();
    }

    public override void CreateRole(string roleName)
    {
        throw new System.NotImplementedException();
    }

    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
    {
        throw new System.NotImplementedException();
    }

    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
    {
        throw new System.NotImplementedException();
    }
}
公共类CustomRoleProvider:RoleProvider
{
/// 
///获取分配给特定用户的角色列表
/// 
///用户的ID
///DbContext
/// 
公共静态列表GetUserRoles(int UserID、UserContext上下文)
{
返回context.UserList
.Where(s=>s.UserID==UserID)
.SelectMany(s=>s.AccessGroup.GroupRoles)
.Select(gr=>gr.RoleID.ToString()).ToList();
}
/// 
///获取分配给特定用户的角色列表
/// 
///用户的用户名[或当前用户的用户名]
///DbContext
/// 
公共静态列表GetUserRoles(字符串用户名、UserContext上下文)
{
返回context.UserList
.Where(s=>s.Username==Username)
.SelectMany(s=>s.AccessGroup.GroupRoles)
.Select(gr=>gr.RoleID.ToString()).ToList();
}
//roleName=RoleId;因此只有ID存储在会话中。。。
public override bool IsUserInRole(字符串用户名、字符串角色名)
{
返回GetUserRoles(username,new UserContext())。包含(roleName);
}
公共重写字符串[]GetRolesForUser(字符串用户名)
{
返回GetUserRoles(username,newusercontext()).ToArray();
}
公共重写字符串[]GetAllRoles()
{
返回新的UserContext().UserRoleList.Select(r=>r.RoleID.ToString()).ToArray();
}
公共覆盖布尔RoleExists(字符串roleName)
{
返回新的UserContext().UserRoleList.Where(r=>r.RoleID.ToString().Equals(roleName)).Count()>0;
}
公共重写字符串ApplicationName
{
获取{return“您的应用程序名”;}
集合{}
}
公共重写字符串[]GetUsersInRole(字符串roleName)
{
抛出新系统。NotImplementedException();
}
公共重写字符串[]FindUsersInRole(字符串roleName,字符串usernameToMatch)
{
抛出新系统。NotImplementedException();
}
public override void AddUsersToRoles(字符串[]用户名,字符串[]角色名)
{
抛出新系统。NotImplementedException();
}
公共重写无效CreateRole(字符串roleName)
{
抛出新系统。NotImplementedException();
}
public override bool DeleteRole(字符串roleName,bool throwOnPopulatedRole)
{
抛出新系统。NotImplementedException();
}
public override void RemoveUsersFromRoles(字符串[]用户名,字符串[]角色名)
{
抛出新系统。NotImplementedException();
}
}

您是否尝试过在身份验证后将AccessItems作为声明加载?你可以缓存它们,这样你就不会在每个请求中点击db。这是我的第一个想法,但我认为我会错误地使用框架,请看MSDN的说法:“声明是一个名称-值对,代表主题是什么,而不是主题可以做什么。”简单地使用@Enoch,tks作为回复。我喜欢你的想法,但我想更好地理解使用缓存策略的框架,例如在登录时加载用户权限,而不是在每个请求上加载。@ViniciusGonçalves您可以创建一个字符串,其中包含分配给用户的角色ID,例如登录方法中的“1,3,4,7,9”。将此字符串存储在会话变量中,然后在需要对页面执行身份验证时检索它。使用
var roleIDs=Session[“roleIDs”].ToString();bool ispermitt=roleIDs.Split(',')。包含(“1”)
检查用户是否具有正确的权限。