细粒度的权限; PrimaryPermission - 角色与权限分离;

发布于 2024-08-30 20:09:08 字数 703 浏览 12 评论 0原文

我在 wcf 服务中使用 PrimaryPermission 一段时间了。 [PrincipalPermission(SecurityAction.Demand, Role = SecurityRoles.CanManageUsers)]

我们的角色前缀为:Can*,这就是我们如何通过内置的 asp.net 会员系统实现细粒度的操作控制。

这使得作为一个业务部门很难知道我们可以为用户提供哪些细粒度的角色。

这是我的新方法,想看看是否有人可以提供反馈,在我实施我的建议之前进行代码审查。

1) aspnet_roles - 业务部门角色

2) 通过创建权限表、Role_Permission 表和 User_Permission 表(多对多)来扩展 asp.net 会员系统

3) 创建自定义 CodeAccessSecurityAttribute + 查看新表 [CustomPermissionCheck(Security.Demand, HasPermission="can*")] 第一次迭代我将静态地新建依赖存储库。理想情况下,我想要一个 aop 样式属性,该属性已将存储库注入 IPermissionRepository.HasPermission(...);

如果我采用新的 aop 方式,我可能会停止从 CodeAccessSecurityAttribute 继承——安全人员对此有何看法?

有其他人解决了这个问题吗?框架中是否有我遗漏的内容?

I've been using PrincipalPermission for a while in wcf services.
[PrincipalPermission(SecurityAction.Demand, Role = SecurityRoles.CanManageUsers)]

Our roles are prefixed with: Can* and is how we achieve fine grained actions control with the built in asp.net membership system.

This makes it hard to know as a business unit what fine grained roles we can give to a user.

Here is my new approach and wanted to see if anyone can provide feedback, code review before i implement my suggestion.

1) aspnet_roles - business unit role

2) Extend the asp.net membership system by creating a permission table and Role_Permission table and User_Permission table (many to many)

3) create custom CodeAccessSecurityAttribute + that looks at new tables
[CustomPermissionCheck(Security.Demand, HasPermission="can*")]
first iteration i'll statically new the dependent repository.. ideally i would like an aop style attribute that has repository injected IPermissionRepository.HasPermission(...);

If i approach new aop way i probably will stop inheriting from CodeAccessSecurityAttribute -- what do the security guys have to say about this?

has anyone else solved this, is there something in the framework that i've missed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花开浅夏 2024-09-06 20:09:08

我想说,如果您使用 ASP.NET,那么您应该实现 自定义 RoleProvider

在您的自定义 RoleProvider 中,您将访问另一个表,该表将业务组链接到细粒度权限。

然后,当您找到用户时,您可以找到他们所在的业务组,并在 RoleProvider 中分配所有适当的角色,而无需更改您拥有的任何现有代码。

它还工作得更好,因为它允许您轻松更改哪些组拥有哪些权限,同时在代码端保持权限的域模型纯粹。

I would say that if you are in ASP.NET, then you should implement a custom RoleProvider.

In your custom RoleProvider, you would access another table which would have the business groups linked to the fine grained permissions.

Then, when you find out the user, you can find out the business group that they are in and assign all of the appropriate roles in the RoleProvider and not change any of the existing code that you have.

It also works better, because it allows you to change what groups have what permissions easily, while keeping the domain model for permissions pure on the code side.

瘫痪情歌 2024-09-06 20:09:08

我实现了第一次迭代,并且运行良好。 [PermissionValidate(SecurityAction.Demand, HasPermission = CensusSchedulerRoles.CanUpdateCensusScheduler)]

public void Demand()
{
    var principal = Thread.CurrentPrincipal;
    if(principal == null || principal.Identity.IsAuthenticated == false)
    {
        throw new SecurityException("Unable to get IPrincipal.");
    }
    if(principal.Identity.IsAuthenticated == false)
    {
        throw new SecurityException("You must be authenticated.");
    }   
     #warning this should be moved to an aop attribute that is injected by a ioc container.
    using (var connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["......."].ConnectionString))
    {
        connection.Open();
        using(var command = new SqlCommand(
        @"
            SELECT COUNT(t.name) FROM
            (
                SELECT p.name, u.UserName FROM 
                    aspnet_Users as u
                    INNER JOIN [User_Permission] as up
                        ON up.user_id = u.UserId
                    INNER JOIN Permission as p
                        ON p.id = up.permission_id
                UNION
                SELECT p2.name, u2.UserName FROM 
                    aspnet_Users as u2
                    INNER JOIN aspnet_UsersInRoles as uir
                        ON uir.UserId = u2.UserId
                    INNER JOIN aspnet_Roles as r
                        ON r.RoleId = uir.RoleId
                    INNER JOIN Role_Permission as rp
                        ON rp.role_id = r.RoleId
                    INNER JOIN Permission as p2
                        ON p2.id = rp.permission_id
            ) as t
            WHERE t.UserName = @username AND t.name = @haspermission
        ", connection))
        {
            command.Parameters.Add("@username", SqlDbType.VarChar).Value = Thread.CurrentPrincipal.Identity.Name;
            command.Parameters.Add("@haspermission", SqlDbType.VarChar).Value = _permissionRequested;

            if( Convert.ToInt32(command.ExecuteScalar()) <=0)
            {
                throw new SecurityException(String.Format("User '{0}' is not assigned permission '{1}'.", principal.Identity.Name, _permissionRequested));
            }
        }
    }
}

I implemented first iteration and it is working nicely. [PermissionValidate(SecurityAction.Demand, HasPermission = CensusSchedulerRoles.CanUpdateCensusScheduler)]

public void Demand()
{
    var principal = Thread.CurrentPrincipal;
    if(principal == null || principal.Identity.IsAuthenticated == false)
    {
        throw new SecurityException("Unable to get IPrincipal.");
    }
    if(principal.Identity.IsAuthenticated == false)
    {
        throw new SecurityException("You must be authenticated.");
    }   
     #warning this should be moved to an aop attribute that is injected by a ioc container.
    using (var connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["......."].ConnectionString))
    {
        connection.Open();
        using(var command = new SqlCommand(
        @"
            SELECT COUNT(t.name) FROM
            (
                SELECT p.name, u.UserName FROM 
                    aspnet_Users as u
                    INNER JOIN [User_Permission] as up
                        ON up.user_id = u.UserId
                    INNER JOIN Permission as p
                        ON p.id = up.permission_id
                UNION
                SELECT p2.name, u2.UserName FROM 
                    aspnet_Users as u2
                    INNER JOIN aspnet_UsersInRoles as uir
                        ON uir.UserId = u2.UserId
                    INNER JOIN aspnet_Roles as r
                        ON r.RoleId = uir.RoleId
                    INNER JOIN Role_Permission as rp
                        ON rp.role_id = r.RoleId
                    INNER JOIN Permission as p2
                        ON p2.id = rp.permission_id
            ) as t
            WHERE t.UserName = @username AND t.name = @haspermission
        ", connection))
        {
            command.Parameters.Add("@username", SqlDbType.VarChar).Value = Thread.CurrentPrincipal.Identity.Name;
            command.Parameters.Add("@haspermission", SqlDbType.VarChar).Value = _permissionRequested;

            if( Convert.ToInt32(command.ExecuteScalar()) <=0)
            {
                throw new SecurityException(String.Format("User '{0}' is not assigned permission '{1}'.", principal.Identity.Name, _permissionRequested));
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文