мелкозернистые разрешения; PrincipalPermission - роли, отделенные от разрешений; - PullRequest
2 голосов
/ 03 мая 2010

Я некоторое время использовал PrincipalPermission в сервисах wcf. [PrincipalPermission (SecurityAction.Demand, Role = SecurityRoles.CanManageUsers)]

Наши роли начинаются с префикса: Can * и это то, как мы добиваемся точного контроля действий с помощью встроенной системы членства asp.net.

Это затрудняет понимание как бизнес-единицы, какие мелкозернистые роли мы можем дать пользователю.

Вот мой новый подход, и я хотел посмотреть, сможет ли кто-нибудь дать отзыв, проверить код, прежде чем я реализую свое предложение.

1) aspnet_roles - роль бизнес-единицы

2) Расширить систему членства asp.net, создав таблицу разрешений и таблицу Role_Permission и таблицу User_Permission (от многих к многим)

3) создать пользовательский CodeAccessSecurityAttribute +, который просматривает новые таблицы [CustomPermissionCheck (Security.Demand, HasPermission = "can *")] На первой итерации я буду статически создавать новый зависимый репозиторий .. в идеале я хотел бы, чтобы атрибут стиля aop имел встроенный репозиторий.

Если я подойду к новому, я, вероятно, перестану наследовать от CodeAccessSecurityAttribute - что скажут об этом парни из службы безопасности?

Кто-нибудь еще решил это, есть что-то в рамках, что я пропустил?

Ответы [ 2 ]

0 голосов
/ 15 мая 2011

Я реализовал первую итерацию, и она работает хорошо. [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 голосов
/ 03 мая 2010

Я бы сказал, что если вы находитесь в ASP.NET, вам следует реализовать пользовательский RoleProvider .

В вашем пользовательском RoleProvider вы получите доступ к другой таблице, в которой бизнес-группы будут связаны с детализированными разрешениями.

Затем, когда вы узнаете пользователя, вы можете выяснить, в какой бизнес-группе он находится, и назначить все соответствующие роли в RoleProvider, а не изменять имеющийся у вас код.

Это также работает лучше, потому что позволяет легко изменять какие группы имеют какие разрешения, сохраняя при этом модель домена для разрешений чисто со стороны кода.

...