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 .