Fine-grained resolutions; PrincipalPermission - roles separate from permissions;

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

Our roles are prefixed with: Can * and how we achieve fine-grained action control with asp.net's built-in membership system.

This makes it difficult for the business unit to understand what small roles we can provide to the user.

Here's my new approach and would like to see if anyone can provide feedback, code review, before I submit my suggestion.

1) aspnet_roles - the role of the business unit

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

3) create custom code CodeAccessSecurityAttribute + that will look for new tables [CustomPermissionCheck (Security.Demand, HasPermission = "can *")] first iteration i statically new dependent repository. Ideally, I would like to use the aop style attribute that the IPermissionRepository.HasPermission (...); repository is built into;

If I come up with a new aop method, I will probably stop inheriting from CodeAccessSecurityAttribute - what can the security guys say about that?

Has anyone else solved this, is there something in the framework that I missed?

+2


a source to share


2 answers


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

In your custom RoleProvider, you will have access to another table where business groups will be associated with fine grained permissions.



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

It also works better because it allows you to change which groups have which permissions easily, while maintaining the domain model for code-side permissions.

0


a source


I have implemented the first iteration and it works 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));
            }
        }
    }
}

      

0


a source







All Articles