Разграничение доступа из кода в WCF - Требования, структурированные с помощью PartialTrustClientBase<T>
ОГЛАВЛЕНИЕ
Требования, структурированные с помощью PartialTrustClientBase<T>
Как можно увидеть на рис. 3, ключевые аспекты WCF, такие как транзакции, надежный обмен сообщениями, неограниченное взаимодействие с безопасностью сообщений и доступ к хранилищу сертификатов, как один требуют полного доверия, делая мою предыдущую версию PartialTrustClientBase<T> бессмысленной в среде частичного доверия. Более того, требование доступа неуправляемого кода практически всеми привязками, кроме привязок HTTP (и привязок WS с защитой сообщений), недопустимо, поскольку уничтожает саму идею CAS для частично доверенного клиента.
Чтобы обеспечить адекватное, безопасное и верное использование WCF частично доверенным клиентом, PartialTrustClientBase<T> предлагает метод Invoke («Вызвать»), определенный как:
protected object Invoke(string operation,params object[] args);
Invoke принимает имя операции, которую следует вызвать, и ее параметры в форме разделенного запятыми массива объектов params. Вместо использования свойства Channel для совершения вызова, Invoke использует отражение. Вот прокси, произведенный от PartialTrustClientBase<T> с использованием метода Invoke:
public class MyContractClient :
PartialTrustClientBase<IMyContract>,IMyContract
{
public MyContractClient() {}
public MyContractClient(string endpointName) :
base(endpointName) {}
public void MyMethod() {
Invoke("MyMethod");
}
}
Invoke сперва потребует нужных полномочий CAS в соответствии с вариантом вызывающего клиента и конечной точкой целевой службы. Если клиенту будут даны эти полномочия, то есть если требования не вызовут исключения безопасности, Invoke программно установит полное доверие и приступит к вызову операции, удовлетворенный наличием у клиента верных полномочий на вызов службы. Такое поведение я зову структурированным требованием полномочия.
Invoke не может использовать атрибут для декларативной установки полного доверия, поскольку это замаскирует любые более детализированные полномочия, которые он требует. Вместо этого реализация Invoke на рис. 2 сперва проверяет, не произведено ли обращение к вызову асинхронно (используя флаг AsyncPattern контракта операции). Если это так, Invoke требует соответствующих полномочий, используя вспомогательный метод DemandAsyncPermissions. После этого Invoke требует синхронных полномочий, используя вспомогательный метод DemandSyncPermissions. Для самого вызова Invoke программно устанавливает полное доверие, используя мой класс CodeAccessSecurityHelper, показанный на рис. 4.
Рис. 4 Класс CodeAccessSecurityHelper
public enum StandardPermissionSet {
Internet,
LocalIntranet,
FullTrust,
Execution,
SkipVerification
}
public static class CodeAccessSecurityHelper {
public static PermissionSet PermissionSetFromStandardSet(
StandardPermissionSet standardSet);
public static void DemandClientPermissions<T>(this ClientBase<T> proxy)
where T : class;public static void DemandAsyncPermissions();
//More members
Метод PermissionSetFromStandardSet берет мое значение перечисления, представляющее один из стандартных наборов полномочий.NET, и возвращает подходящий экземпляр PermissionSet (см. рис. 5). PermissionSet, как и предполагает его имя, является коллекцией полномочий, но может также представлять сверхнабор полномочий полного доверия (который больше похож на единственное полномочие, чем на набор отдельных полномочий). Класс PermissionSet поддерживает интерфейс IStackWalk, позволяющий установить модификатор анализа стека, скажем модификатор, останавливающий требование к полномочиям в наборе полномочий, утверждая, что у всех источников вызова выше по стеку имеются эти полномочия. Модификатор анализа стека удаляется автоматически при возвращении из установившего его метода. Его можно также удалить напрямую с помощью статического метода RevertAssert набора PermissionSet.
Рис. 5 PermissionState и PermissionSet
public enum StandardPermissionSet {
Internet,
LocalIntranet,
FullTrust,
Execution,
SkipVerification
}
public static class CodeAccessSecurityHelper {
public static PermissionSet PermissionSetFromStandardSet(
StandardPermissionSet standardSet);
public static void DemandClientPermissions<T>(this ClientBase<T> proxy)
where T : class;public static void DemandAsyncPermissions();
//More members
Вспомогательные методы DemandAsyncPermissions и DemandSyncPermissions класса PartialTrustClientBase<T> используют соответствующие методы CodeAccessSecurityHelper для выполнения своих требований.
На диаграмме на рис. 6 показаны структурированные требования, создаваемые PartialTrustClientBase<T>.Invoke в качестве функции использованной привязки, и другие аспекты ситуации, такие как использование транзакций, надежности, доступа к хранилищу сертификатов, диагностики, обратных вызовов и асинхронных вызовов.
Рис. 6 Структурированные требования безопасности PartialTrustClientBase<T>
Случай | Полномочия |
---|---|
TCP | Полномочие безопасности с исполнением, неограниченным DNS, полномочием сокету подключаться к порту на целевом узле |
IPC | Полномочие безопасности с исполнением, управлением политикой и доказательствами |
WS, Базовый | Полномочие безопасности с исполнением и веб-полномочие на подключение к URI |
WS-Dual | Полномочие безопасности с исполнением и веб-полномочие на подключение к URI, а также веб-полномочие на прием обратных вызовов на адрес обратного вызова, минимальное полномочие на размещение ASP.NET. |
MSMQ | Полномочие безопасности с исполнением, полномочие MSMQ на отправку запроса |
RM через TCP | Полномочие безопасности с управлением политикой |
Учетные данные имени пользователя, дуплекс через TCP, асинхронные вызовы(AsyncPattern), защита сообщений с согласованием сертификата службы, но без его проверки | Полномочие безопасности с управлением политикой и управлением доказательствами |
Безопасность Windows с интерактивными учетными данными пользвателя | Полномочие среды на чтение USERNAME |
Безопасность Windows с альтернативными учетными данными | Полномочие безопасности на управление участником |
Распространение транзакций | Неограниченное полномочие распределенных транзакций |
Учетные данные имени пользователя, защита сообщений без согласования сертификата службы или с его проверкой, учетные данные сертификата | Полномочие хранилища на перечисление хранилищ, открытие хранилища и перечисление сертификатов |
Диагностическое отслеживание | Полномочие среды на чтение COMPUTERNAME, полномочие файлового ввода/вывода на обнаружение пути, добавление, запись в файлы журнала |