Безопасность в Java

Начнем с безопасности JavaSE, т.к. на эти механизмы безопасности операется JavaEE

Java дает большую гибкость в назначении прав, в том числе:
 * Создание текущим потоком загрузчика классов
 * Доступ к файлам
 * Доступ к передаваемым JRE свойствам (java version, например)
 * Остановка работы виртуальной машины
 * Получени класса доступа к членам другого класа

В первых версиях Java безопасность была кодо-центричной (права назначались коду) и права назначались в зависимости от того код получен (codebase - свойства класса откуда он взят или URL - загруженного ресурса).

CodeSource - источник кода, отличие от CodeBase то, что CodeSource инкапсулирует откуда код взят, и дополнительно сертификаты, позволяющий удостоверить автора.

ProtectionDomain - домен безопасности. Объединяет CodeSource и права, которыми он обладает.

С каждым загруженнм классом ассоциирован ProtectionDomain и его можно получить Application.class.getProtectionDomain; - т.е. ч.з. рефлексию и из него можно получить codeSourece

Политика безопасности или SecurityPolicy
Политика безопасности определяет права для всех классов в приложении. На основе политики создается домен безопасности.

Для работы с правами (полномочиями) используется базовый класс java.security.Permission, от него наследуются все остальные классы, определяющие права на все аперации.

К примеру, java.security.AllPermission


 * java.security.BasicPermission - можно создавать собственные именованные права.
 * java.io.FilePermission - позволяет создавать права на доступ к различным объектам файловой системы.
 * java.net.SocketPermission - права с работой с сетью
 * java.lang.PropertyPermission - на работу с JRE, например java version

Классы разрешения разбросаны по разным пакетом и обычно определяют права доступа на то, что находится в пакете.

Пример создания объекта полномочий для доступа к файлу Permission p = new FilePermission("temp/*", "read");

Полномочия назначаются с помощью политик безопасности (хотя можно из кода, но так не пользуются). Тогда назначение полномочий может быть в файле политик так: grant {   permission java.io.FilePermission "c:/temp/testFile/*", "read,write" }

Политики
Как правило, используется политика безопасности по умолчанию, она находится в ${java.home}/lib/security/java.policy

Политику по умолчанию можно поменять чз файл ${java.home}/.java.policy, но так тоже не делают, т.к. это заменит политику безопасности для всех приложений

Для замены политики для конкретного приложения используется передача свойства при запуске java-машины.

java -Djava.security.policy=myURL MyClass

Так же можно установить из программы ч.з. setProperty

Пример файла политики: grant signedBy "javaguy", codease "http://securtycode.com/*" {   permission java.io.FilePermission "/export/home/test/*", "read,write" }

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

Как правило, при написании локальных приложений, менеджер безопасности не создается. Поэтому, проверки автоматически не выполняются, но без менеджера безопасности можно выполнять только локальный код (код проекта). Ничего загружать, работать с кодом с других компьютеров нельзя.

Чтобы узнать есть менеджер безопасности или нет, можно воспользоватться методом SecurityManager securityManager = System.getSeucirytManager; if (secuirytManager == null) { securityManager = System.getSecurityManager(new SecurityManager); }

После получения МБ, можно проверить есть права доступа или нет. Для этого МБ предоставляет множество методов начинающихся с check Permission p = new FilePermission( "temp/*", "read");

Как правило, все эти обращаются к SecuirtyManager.checkPermission;

Если разрешений нету, то будет сгенерированно исключение SecurityException;

Менеджер безопасности является единой точкой для проверки прав, но он делегирует проверку прав для доступа к конкретному объекту классу

java.security.AccessController, у которого есть свой метод checkPermission причем он статический и с ним можно работать не создавая SecurityManager (но так лучше не делать).

Пример проверки без создания SecuirtyManager try { AccessController.checkPermssion( new FilePermission("temp/*, ... }

Пример поволяет просмотреть полномочия для конкретного источника кода: URL codebase = null; try { codebase = new URL("http://www.it.ru"); .. catch {} CodeSource cs = new CodeSource (codebase, null); ... Пример файлов политик grant codebase "http://it.ru/-" { permission java.util.PropertyPermission "*", "read"; }

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