Управление правами доступа

В этом разделе говорится о программном подходе в решении вопросов безопасности и прав доступа для SberMobile Server.

Доступ к контекстным данным

Многие методы интерфейсов Context и ContextManager допускают параметры типа CallerController. Контроллер вызывающего объекта - это объект, который включает в себя эффективные права доступа вызывающей стороны. Существует два общих правила использования контроллеров вызывающего объекта:

  • Любой код сервера (драйверы устройства и плагины) должны передать экземпляр CallerController каждому методу, который его способен принять. Если это не удается выполнить, на вызывающей стороне уровень права доступа не будет определен, и, таким образом, большинство вызовов завершаться ошибкой или возвратом нулевых значений.
  • Любой удаленный код (приложения, использующие API SberMobile Server или Агенты на Java) должен использовать методы, которые не принимают контроллеры вызывающего объекта или передают нулевые значения. Это будет отлично работать, поскольку код клиента не выполняет проверки прав доступа, в то время как запрошенная операция удаленного сервера будет тем не менее учитывать уровень прав доступа, полученный во время авторизации (вызывает функцию login() корневого контекста).

Получение контроллера вызывающего объекта

Код сервера может получить контроллеры вызывающего объекта несколькими способами:

  • Создать экземпляр UncheckedCallerController, чтобы запретить любое право проверки и полного доступа. Это следует выполнить при помощи системного кода, который, как предполагается, не выполняет операции с правами доступа пользователя системы.
  • Получить Контроллер вызывающего объекта, вызывая метод getCallerController() от ServerContext (или метод getCallerController() от DeviceContext). Этот контроллер будет разрешать права доступа системного пользователя, которому принадлежит учетная запись устройства. Этот способ получения контроллеров вызывающего объекта в большей степени применимо для кода Драйвера устройства.

Расширение контекстов

Когда драйвер устройства плагина пользователя добавляет определения переменных, функции или события в контекст сервера, он может назначить для них пользователские уровни доступа, используя методы VariableDefinition.setReadPermissions(), VariableDefinition.setWritePermissions(), FunctionDefinition.setPermissions() и EventDefinition.setPermissions(). Если уровень прав доступа для определения равно нулю, оно будет соответствовать уровню доступа  родительского контекста. Обратите внимание, что настройка уровней доступа к определению ниже или равному уровню доступа к конексту является бессмысленным.

Чтобы получить определенные заранее значения уровней с различными правами доступа, используйте следующий код:

Уровень доступа

Код

Отсутствует

LinkServerPermissionChecker.getNullPermissions()

Наблюдатель

LinkServerPermissionChecker.getObserverPermissions()

Оператор

LinkServerPermissionChecker.getOperatorPermissions()

Администратор

LinkServerPermissionChecker.getManagerPermissions()

Инженер

LinkServerPermissionChecker.getEngineerPermissions()

Администратор

LinkServerPermissionChecker.getAdminPermissions()

Проверка прав доступа вручную

Иногда нужно проверить права доступа особых авторизованных сущностей (представленных CallerController). Это можно сделать с помощью инструмента проверки серверных прав доступа, представленным интерфейсом PermissionChecker.

Экземпляр инструмента проверки прав доступа может быть получен с помощью метода getPermissionChecker() от ServerContextManager, который, в свою очередь, возвращен методом getContextManager() правильно настроенных контекстов сервера (например, контексты, унаследованные от BaseServerContext, EditableChildrenContext или EditableChildContext).

Действующий уровень прав доступа CallerController в особом контексте можно проверить с помощью метода (CallerController caller, Permissions requiredPermissions, Context accessedContext) от PermissionChecker. Далее представлен пример:

boolean checking = caller.isPermissionCheckingEnabled();

        

boolean admin = getContextManager().getPermissionChecker().has(caller, ServerPermissionChecker.getEngineerPermissions(), this);

        

if (!admin && checking)

{

  throw new ContextException("Not an administrator");

}