21.03.2024, 17:46 | #1 |
Участник
|
Как работают InteropPermission и fileIOPermission?
AX2009
Помогите, пожалуйста, понять, как работают InteropPermission и fileIOPermission? Есть Job. Мне нужно получить путь к временной папке, независимо от того, где исполняется код: на сервере или клиенте. Для тестирования написала Job запускаю через menuItem c calledFrom = server для исполнения на сервере. И просто по F5 для исполнения на кленте X++: static server void My_test (Args _args) { FilePath tmpPath; FileIOPermission fileIOPermission; InteropPermission perm; ; // perm = new InteropPermission(InteropKind::ClrInterop); // perm.assert(); fileIOPermission = new FileIOPermission('','r'); fileIOPermission.assert(); if(isRunningOnServer()) { info(strFmt('Server')); tmpPath = WinAPIServer::getTempPath(); } else { info(strFmt('Client')); tmpPath = WinAPI::getTempPath(); } //CodeAccessPermission::revertAssert(); info(strFmt('tmpPath %1', tmpPath)); Вопросы 1 ) Почему, если я убираю X++: fileIOPermission = new FileIOPermission('','r'); fileIOPermission.assert(); получаю ошибку Request for the permission of type 'FileIOPermission' failed. (S)\Classes\FileIOPermission\demand (S)\Classes\WinAPIServer\getTempPath - line 13 То есть, если в моем коде есть FileIOPermission, то вторичный FileIOPermission, что внутри tmpPath = WinAPIServer::getTempPath(); отрабатывает. А как только свои две строки убираю, то выдается эта ошибка. 2) Почему я не могу раскомментировать строки X++: // perm = new InteropPermission(InteropKind::ClrInterop); // perm.assert(); Multiple calls to CodeAccessPermission.Assert (S)\Classes\FileIOPermission\assert (S)\Jobs\My_test - line 38 (S)\Classes\MenuFunction\runServer Спасибо Последний раз редактировалось Lankey; 21.03.2024 в 17:49. |
|
21.03.2024, 17:48 | #2 |
Участник
|
Для наглядности, вот код WinAPIServer::getTempPath()
X++: #define.maxPath(260) public server static str getTempPath() { FileIOPermission fileIOPerm; InteropPermission interopPerm; str tempPath; // check file I/O permission fileIOPerm = new FileIOPermission('','r'); fileIOPerm.demand(); // get dll interop permission interopPerm = new InteropPermission(InteropKind::ClrInterop); interopPerm.assert(); tempPath = System.IO.Path::GetTempPath(); CodeAccessPermission::revertAssert(); return tempPath; } |
|
21.03.2024, 19:08 | #3 |
Участник
|
X++: #define.maxPath(260) public server static str getTempPath(boolean _setPermission = true) { FileIOPermission fileIOPerm; InteropPermission interopPerm; str tempPath; Set permissionSet; ; permissionSet = new Set(Types::Class); if(_setPermission) { // check file I/O permission permissionSet.add( new FileIOPermission('','r')); //fileIOPerm = new FileIOPermission('','r'); //fileIOPerm.demand(); } // get dll interop permission permissionSet.add(new InteropPermission(InteropKind::ClrInterop)); //interopPerm = new InteropPermission(InteropKind::ClrInterop); //interopPerm.assert(); CodeAccessPermission::assertMultiple(permissionSet); tempPath = System.IO.Path::GetTempPath(); return tempPath; } |
|
21.03.2024, 20:22 | #4 |
Участник
|
Спасибо за пример, но мой код , приведенный выше, тоже работает
Я хочу понять, как работают InteropPermission и fileIOPermission, Тк не понимаю, откуда получаются вышеприведенные ошибки, когда меняю код указанным образом В вашем примере, кстати, есть закомменченные demand и assert. Вы можете объяснить, когда использутее demand, а когда assert? Последний раз редактировалось Lankey; 21.03.2024 в 20:30. |
|
21.03.2024, 22:33 | #5 |
Участник
|
1. Отдельные команды assert() - взаимоисключающие. Т.е. последующий assert() вызывает конфликт с ранее настроенным assert(). Непонятно, а какие же права надо настраивать? Будет ошибка "Multiple calls to CodeAccessPermission.Assert"
Если надо дать несколько разных типов прав, то используют специальную конструкцию CodeAccessPermission::assertMultiple() с переданным списком типов 2. assert - это дать права demand - это запросить права (проверить наличие), настроенные ранее. Т.е. demand сам по себе никаких прав не дает. Это своеобразная "напоминалка" о том, что такие права надо бы дать ранее в коде. Если в коде встречается fileIOPerm.demand(), то это означает, что где-то ранее должна была быть команда fileIOPerm.assert() // check file I/O permission - обратите внимание на слово "check".
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
За это сообщение автора поблагодарили: S.Kuskov (5), axm2017 (7). |
22.03.2024, 10:39 | #6 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
2.
assert - это дать права demand - это запросить права (проверить наличие), настроенные ранее. Т.е. demand сам по себе никаких прав не дает. Это своеобразная "напоминалка" о том, что такие права надо бы дать ранее в коде. Если в коде встречается fileIOPerm.demand(), то это означает, что где-то ранее должна была быть команда fileIOPerm.assert() . Не могли бы Вы пояснить немного: 1) Зачем существует demand, если уже и так запросили, что нужно, через assert ? Это как-то зависит от того, где запросили (на сервере или клиенте?) или у assert есть scope? Я же не "напоминаю" коду о том. что объявила перееменные или там вызывала функции ранее Цитата:
2) Почему мы запрашиваем разными классами (InteropPermission и fileIOPermission), что логично, а вот убираем одной CodeAccessPermission::revertAssert(), а не отдельно fileIOPermission::revertAssert и InteropPermission ::revertAssert . 3) revertAssert , как я понимаю, отменит все запросы, даже те, что были наложены в вызывающей функции , а не текущей? 4) revertAssert зачастую в конце кода, где выше по тексту запросили уже права, не делается. Это ошибка или есть в этом логика? |
|
22.03.2024, 11:08 | #7 |
Участник
|
Цитата:
Принудительно создает SecurityException во время выполнения, если все вызывающие методы, расположенные выше в стеке вызовов, не получили разрешения, указанного текущим экземпляром. https://learn.microsoft.com/ru-ru/do...t-plat-ext-8.0 |
|
22.03.2024, 11:15 | #8 |
Administrator
|
Сразу оговорюсь - правильный ответ могут дать только архитекторы MS, которые задумывали эту логику. Нам лишь остается строить гипотезы. Тем не менее:
Цитата:
Сообщение от Lankey
Не могли бы Вы пояснить немного:
1) Зачем существует demand, если уже и так запросили, что нужно, через assert ? Это как-то зависит от того, где запросили (на сервере или клиенте?) или у assert есть scope? Я же не "напоминаю" коду о том. что объявила перееменные или там вызывала функции ранее Я бы поняла, если бы была проверкка типа "If demand() = false" then asset() .... но так этот метод не используется. Аналогию можно провести с абстрактными методами. Один разработчик пишет метод и добавляет ему модификатор abstract, а другой (создавая наследник класса) вынужден перекрывать абстрактный метод, т.к. это требование первоначального разработчика Цитата:
Цитата:
Т.е. "для красоты кода" - нужно выдавать разрешения и их отзывать. Но... если разрешения не отозвать - то код "не сломается", хотя всякие Best Practice конечно скажут, что выданное разрешение надо обязательно отозвать.
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: Lankey (1). |