Въведение в Java SecurityManager

Java Top

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА

1. Общ преглед

В този урок ще разгледаме вградената инфраструктура за сигурност на Java, която е деактивирана по подразбиране. По-конкретно, ще разгледаме основните му компоненти, точки на разширение и конфигурации.

2. SecurityManager в действие

Може да е изненада, но настройките по подразбиране на SecurityManager забраняват много стандартни операции :

System.setSecurityManager(new SecurityManager()); new URL("//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. SecurityManager

Един от основните компоненти във вградената инфраструктура за сигурност е java.lang SecurityManager . Той има няколко метода checkXxx като checkConnect , който разрешаваше опита ни да се свържем с Google в горния тест. Всички те делегират метода checkPermission (java.security.Permission) .

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

java.security.Permission екземплярите представляват заявки за оторизация. Стандартните класове JDK ги създават за всички потенциално опасни операции (като четене / запис на файл, отваряне на сокет и т.н.) и ги предават на SecurityManager за правилно упълномощаване.

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

Определяме разрешенията в специален формат на политиката. Тези разрешения са под формата на записи за безвъзмездна помощ :

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

В програмния код горното правило не е задължително. Можем да посочим никакво поле там или да използваме подписани (интегрирани със съответните сертификати в хранилището на ключове) или принципали ( java.security.Principal, прикрепени към текущата нишка чрез javax.security.auth.Subject ). Можем да използваме всяка комбинация от тези правила .

По подразбиране 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.

Дъно на Java

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА