Рубрики
Без рубрики

Введение в Java SecurityManager

Краткий и практический обзор Java Security Manager.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы рассмотрим встроенную инфраструктуру безопасности Java, которая по умолчанию отключена. В частности, мы рассмотрим его основные компоненты, точки расширения и конфигурации.

2. Менеджер безопасности в действии

Это может быть сюрпризом, но по умолчанию Менеджер безопасности настройки запрещают | многие стандартные операции :

System.setSecurityManager(new SecurityManager());
new URL("http://www.google.com").openConnection().connect();

Здесь мы программно включаем контроль безопасности с настройками по умолчанию и пытаемся подключиться к google.com.

Тогда мы получаем следующее исключение:

java.security.AccessControlException: access denied ("java.net.SocketPermission"
  "www.google.com:80" "connect,resolve")

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

3. Пример использования

Эта инфраструктура безопасности была доступна с Java 1.0. Это было время, когда апплеты – Java – приложения, встроенные в браузер, – были довольно распространены. Естественно, необходимо было ограничить их доступ к системным ресурсам.

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

Например, рассмотрим, что у нас есть экземпляр Tomcat, где сторонние клиенты могут размещать свои веб-приложения. Мы не хотим, чтобы они выполняли такие операции, как System.exit () , потому что это повлияло бы на другие приложения и, возможно, на всю среду.

4. Дизайн

4.1. Менеджер по безопасности

Одним из основных компонентов встроенной инфраструктуры безопасности является java.lang SecurityManager . Он имеет несколько методов checkXxx , таких как check Connect , которые разрешали нашу попытку подключиться к Google в приведенном выше тесте. Все они делегируются в checkPermission(java.security.Разрешение) метод.

4.2. Разрешение

java.безопасность.Экземпляры разрешений означают запросы на авторизацию. Стандартные классы JDK создают их для всех потенциально опасных операций (таких как чтение/запись файла, открытие сокета и т. Д.) И передают их в SecurityManager Для надлежащей авторизации.

4.3. Конфигурация

Мы определяем разрешения в специальном формате политики. Эти разрешения принимают форму записей grant :

grant codeBase "file:${{java.ext.dirs}}/*" {
    permission java.security.AllPermission;
};

Приведенное выше правило codeBase является необязательным. Мы можем вообще не указывать там поля или использовать signedBy (интегрированный с соответствующими сертификатами в хранилище ключей) или principal ( java.security.Принципал присоединен к текущему потоку через javax.security.auth.Тема ). Мы можем использовать любую комбинацию этих правил .

По умолчанию JVM загружает файл общей политики системы, расположенный по адресу < java.home>/lib/security/java.policy . Если мы определили какую-либо локальную политику пользователя в /.java.policy , JVM добавляет ее в системную политику.

Также можно указать файл политики через командную строку: – Djava.security.policy=/my/policy-file . Таким образом, мы можем добавить политики к ранее загруженным системным и пользовательским политикам.

Существует специальный синтаксис для замены всех системных и пользовательских политик (если таковые имеются) – двойной знак равенства: – Djava.security.policy==/my/policy-file

5. Пример

Давайте определим пользовательское разрешение:

public class CustomPermission extends BasicPermission {
    public CustomPermission(String name) {
        super(name);
    }

    public CustomPermission(String name, String actions) {
        super(name, actions);
    }
}

и общий сервис, который должен быть защищен:

public class Service {

    public static final String OPERATION = "my-operation";

    public void operation() {
        SecurityManager securityManager = System.getSecurityManager();
        if (securityManager != null) {
            securityManager.checkPermission(new CustomPermission(OPERATION));
        }
        System.out.println("Operation is executed");
    }
}

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

java.security.AccessControlException: access denied
  ("com.baeldung.security.manager.CustomPermission" "my-operation")

    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at com.baeldung.security.manager.Service.operation(Service.java:10)

Мы можем создать ваш /.java.policy файл со следующим содержимым и попытаться повторно запустить приложение:

grant codeBase "file:" {
    permission com.baeldung.security.manager.CustomPermission "my-operation";
};

Сейчас это работает просто отлично.

6. Заключение

В этой статье мы проверили, как организована встроенная система безопасности JDK и как мы можем ее расширить. Несмотря на то, что целевой вариант использования относительно редок, полезно знать об этом.

Как обычно, полный исходный код этой статьи доступен на GitHub .