![]() |
#1 |
Участник
|
![]()
Коллеги, поделитесь опытом, кто как реализует хранение настроек плагинов. Я имею в виду, например, параметры доступа к внешним ресурсам, вроде строк подключения к БД и пр.
Для себя выделил несколько возможных вариантов, все со своими плюсами и минусами. Да и кстати, речь идет об on-premises (с онлайном, понятно будут другие варианты). |
|
![]() |
#2 |
Moderator
|
Однозначно не рекомендую варианты с файлом и внешним сервисом. Файл нельзя достать из песочницы + возникают дополнительные сложности с мульти-тенант развертыванием (несколько баз организации на одном сервере) и переносом решения. Кроме того, будет серьезная просадка производительности за счет чтения из файла. Для плагинов это не столь критично, так как каждый инстанс создается один раз, а вот для рабочих процессов ситуация будет однозначно хуже.
MS использует сущности с атрибутами (отдельные объекты под группу настроек). Перенос рекомендуется делать через Package Deployer / Configaration Migration. Не совсем понятно, почему Action не защищен от пользователей? C лукапами, пожалуй, тоже нет проблем. Вцелом, я рассматривую Action как альтернативу сущностям, но они создают определенные сложности при обновлении:
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. ![]() ![]() |
|
![]() |
#3 |
Участник
|
Цитата:
По поводу сущностей, есть одна проблема. Давай всем пользователям доступ к сущности настроек - это значит любой пользователь через расширенный поиск или импорт сможет все посмотреть. Если права на чтение будут только у админа, значит для каждого шага плагина, который использует настройки нужно указывать этого пользователя в Run in user's context, чтобы от имени этого пользователя можно было обратиться к настройкам. А значение этого поля при переносе со среды на среду может слетать. |
|
![]() |
#4 |
Moderator
|
Вы можете использовать пользователя SYSTEM он один на все CRM в мире.
p.s. Альтернатива, как всегда, утки - для этого и существует secure config. Есть готовые скрипты PowerShell чтобы можно было править их автоматизированно: https://github.com/WaelHamze/xrm-ci-framework
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. ![]() ![]() |
|
![]() |
#5 |
Чайный пьяница
|
Цитата:
Сообщение от ZooY
![]() Потому что вызвать его может любой пользователь. Защита основана только на том, что пользователь не знает ключей настроек.
По поводу сущностей, есть одна проблема. Давай всем пользователям доступ к сущности настроек - это значит любой пользователь через расширенный поиск или импорт сможет все посмотреть. Если права на чтение будут только у админа, значит для каждого шага плагина, который использует настройки нужно указывать этого пользователя в Run in user's context, чтобы от имени этого пользователя можно было обратиться к настройкам. А значение этого поля при переносе со среды на среду может слетать. 1. Все настройки хранятся в кастономной сущности (одна запись и много полей или много записей типа пара ключ/значение - на ваше усмотрение). 2. У обычных пользователей нет прав на зачитку этих сущностей. 3. В коде плагинов при помощи подхода, указанного ранее, получаете доступ к настройкам вне зависимости от того, кто вызвал запуск плагина - простой юзер или юзер с доступом к настройкам.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
![]() |
#6 |
Участник
|
Цитата:
Если пользователь не указан явно, то подставляется Calling User, т.е. в контексте плагина свойства UserId и InitiatingUserId равны и ссылаются на конченого пользователя (прав на чтение настроек у которого нет). Это логично с точки зрения безопасности, но создает проблему в случае с настройками. В принципе, нет проблемы указать привилегированного пользователя при настройках шага плагина, но проблема в том, что порой эта настройка не переноситься при переносе плагина решением. Возможно дело в каких то отличиях в именовании пользователя и возможно этот момент можно отладить. |
|
![]() |
#7 |
Чайный пьяница
|
Читаем внимательно это - https://docs.microsoft.com/en-us/dot...s-general-ce-9
А именно, цитирую: Код: When called in a plug-in, a null value indicates the SYSTEM user
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
|
За это сообщение автора поблагодарили: ZooY (1). |
![]() |
#8 |
Участник
|
![]()
У меня какой то взрыв мозга... Попытался проверить поведение Organization Service в плагине при разных идентификаторах пользователя...
Попробовал получать экземпляр сервиса с разными идентификаторами пользователей, для каждого экземпляра выполнял WhoAmIRequest и надеялся получить разных пользователей на выходе. Собственно, вот код плагина: X++: public class GetUsers : IPlugin { public void Execute(IServiceProvider serviceProvider) { var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); var result = ""; var service1 = factory.CreateOrganizationService(null); result += $"null = {GetUserInfo(service1)}"; var service2 = factory.CreateOrganizationService(Guid.Empty); result += $"Guid.Empty ({Guid.Empty}) = {GetUserInfo(service2)}"; var service3 = factory.CreateOrganizationService(context.UserId); result += $"UserId ({context.UserId}) = {GetUserInfo(service3)}"; var service4 = factory.CreateOrganizationService(context.InitiatingUserId); result += $"InitiatingUserId ({context.InitiatingUserId}) = {GetUserInfo(service4)}"; throw new InvalidPluginExecutionException(result); } private static string GetUserInfo(IOrganizationService service) { var request = new WhoAmIRequest(); var response = (WhoAmIResponse)service.Execute(request); var userId = response.UserId; var user = service.Retrieve("systemuser", userId, new ColumnSet("fullname")); var data = $"{userId} | {user.GetAttributeValue<string>("fullname")}{Environment.NewLine}"; return data; } } X++: null = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM
Guid.Empty (00000000-0000-0000-0000-000000000000) = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM
InitiatingUserId (c69c88fb-4e41-e811-a214-83daa2756e35) = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM
UserId (e73922d1-d7ec-e811-a224-ddda898a939f) = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM Как так? |
|
![]() |
#9 |
Чайный пьяница
|
Покажите, пожалуйста, настройку шага из Plugin Registration Tool-а.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
![]() |
#10 |
Участник
|
Вот...
|
|
![]() |
#11 |
Участник
|
Еще попробовал посоздовать записи от имени разных сервисов... Результат - все записи созданы от имени SYSTEM. Попробовал на двух системах - 2016 и 365
|
|
![]() |
#12 |
Чайный пьяница
|
Попробуйте сменить "Run in User's Context" на "Calling User".
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
![]() |
#13 |
Участник
|
Попробовал. Ничего не поменялось (кроме того что UserId и InitiatingUserId стали ровны).
|
|
![]() |
#14 |
Moderator
|
Я наблюдал похожее, когда службы CRM (в частности, application pool) были запущены под учетными записями пользователей. Вы точно ничего не запустили под Натальей Вороновой?
![]()
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. ![]() ![]() |
|
![]() |
#15 |
Участник
|
Цитата:
Кроме того я проверял на 2 системах вообще в двух разных компаниях. Даже способ развертывания и версии CRM отличаются. Картина одинаковая - все что делает сервис в плагине делается от имени SYSTEM. Может кто-то у себя сможет проверить, код плагина в посте выше... Сравним результаты... |
|
![]() |
#16 |
Участник
|
Попробуйте вот так, без WhoAmIRequest
X++: result += string.Format("Caller User Id = {0}",((OrganizationServiceProxy)factory.CreateOrganizationService(context.UserId)).CallerId); result += string.Format("User System Id = {0}", ((OrganizationServiceProxy)factory.CreateOrganizationService(null)).CallerId);
__________________
Читайте SDK!!! |
|
![]() |
#17 |
Участник
|
У меня задача не ID верные получить, а убедиться, что имперсонализация в сервисе работает и сервис выполняет действия от имени указанных пользователей. А он почему то этого не делает.
|
|
![]() |
#18 |
Участник
|
Цитата:
Использовать из плагина WhoAmIRequest нет смысле, он всегда вернет SYSTEM СРМ же работает на основании CallerId поэтому я и хотел что бы ва проверили Я такой трик с SYSTEM использую очень часто и все работает в соответствии с правами эзера, систем видит все, остальные юзеры только то что положено
__________________
Читайте SDK!!! |
|
![]() |
#19 |
Участник
|
CallerId я проверил - он совпадает с ID пользователя (в случае null - нулевой GUID, в случае с Empty - равен UserId).
То есть вы проверяли и импенсонализация все таки работает и на запросы накладываются все ограничения в соответствии с ролями пользователей, даже не смотря на то, что везде (даже в createdby, modifiedby) фигурирует SYSTEM? |
|
Теги |
plug-in, settings |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|