Einführung in den Java SecurityManager

Java Top

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Übersicht

In diesem Tutorial werfen wir einen Blick auf die integrierte Sicherheitsinfrastruktur von Java, die standardmäßig deaktiviert ist. Insbesondere werden wir die Hauptkomponenten, Erweiterungspunkte und Konfigurationen untersuchen.

2. SecurityManager in Aktion

Es mag eine Überraschung sein, aber die Standardeinstellungen von SecurityManager erlauben viele Standardvorgänge nicht :

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

Hier aktivieren wir programmgesteuert die Sicherheitsüberwachung mit Standardeinstellungen und versuchen, eine Verbindung zu google.com herzustellen.

Dann bekommen wir folgende Ausnahme:

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

Es gibt zahlreiche andere Anwendungsfälle in der Standardbibliothek - zum Beispiel das Lesen von Systemeigenschaften, das Lesen von Umgebungsvariablen, das Öffnen einer Datei, das Reflektieren und das Ändern des Gebietsschemas, um nur einige zu nennen.

3. Anwendungsfall

Diese Sicherheitsinfrastruktur ist seit Java 1.0 verfügbar. Dies war eine Zeit, in der Applets - in den Browser eingebettete Java-Anwendungen - ziemlich häufig waren. Natürlich musste der Zugriff auf Systemressourcen eingeschränkt werden.

Applets sind heutzutage veraltet. Die Durchsetzung der Sicherheit ist jedoch immer noch ein tatsächliches Konzept, wenn in einer Situation Code von Drittanbietern in einer geschützten Umgebung ausgeführt wird .

Angenommen, wir haben eine Tomcat-Instanz, in der Clients von Drittanbietern ihre Webanwendungen hosten können. Wir möchten nicht, dass sie Vorgänge wie System.exit () ausführen, da dies Auswirkungen auf andere Anwendungen und möglicherweise die gesamte Umgebung haben würde.

4. Design

4.1. Sicherheitsmanager

Eine der Hauptkomponenten in der integrierten Sicherheitsinfrastruktur ist java.lang SecurityManager . Es gibt mehrere checkXxx- Methoden wie checkConnect , die unseren Versuch autorisierten, im obigen Test eine Verbindung zu Google herzustellen . Alle von ihnen delegieren an die Methode checkPermission (java.security.Permission) .

4.2. Genehmigung

java.security.Permission- Instanzen stehen für Autorisierungsanforderungen. Standard-JDK-Klassen erstellen sie für alle potenziell gefährlichen Vorgänge (wie Lesen / Schreiben einer Datei, Öffnen eines Sockets usw.) und geben sie zur ordnungsgemäßen Autorisierung an SecurityManager weiter .

4.3. Aufbau

Wir definieren Berechtigungen in einem speziellen Richtlinienformat. Diese Berechtigungen haben die Form von Zuschusseinträgen :

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

Die obige CodeBase- Regel ist optional. Wir können überhaupt kein Feld angeben , oder verwenden signedBy (integriert mit entsprechenden Zertifikaten in dem Schlüsselspeicher) oder Haupt ( java.security.Principal an den aktuellen Thread über javax.security.auth.Subject ). Wir können jede Kombination dieser Regeln verwenden .

Standardmäßig lädt die JVM die allgemeine Systemrichtliniendatei unter < java.home> /lib/security/java.policy . Wenn wir in /.java.policy eine benutzerlokale Richtlinie definiert haben , hängt die JVM diese an die Systemrichtlinie an.

Es ist auch möglich, eine Richtliniendatei über die Befehlszeile anzugeben: - Djava.security.policy = / my / policy-file . Auf diese Weise können wir Richtlinien an die zuvor geladenen System- und Benutzerrichtlinien anhängen.

Es gibt eine spezielle Syntax zum Ersetzen aller System- und Benutzerrichtlinien (falls vorhanden) - doppeltes Gleichheitszeichen: - Djava.security.policy == / my / policy-file

5. Beispiel

Definieren wir eine benutzerdefinierte Berechtigung:

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

und ein gemeinsamer Dienst, der geschützt werden sollte:

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"); } }

Wenn wir versuchen, es mit aktiviertem Sicherheitsmanager auszuführen, wird eine Ausnahme ausgelöst:

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)

Wir können unsere Datei /.java.policy mit dem folgenden Inhalt erstellen und versuchen, die Anwendung erneut auszuführen :

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

Es funktioniert jetzt ganz gut.

6. Fazit

In diesem Artikel haben wir überprüft, wie das integrierte JDK-Sicherheitssystem organisiert ist und wie wir es erweitern können. Obwohl der Zielanwendungsfall relativ selten ist, ist es gut, sich dessen bewusst zu sein.

Wie üblich ist der vollständige Quellcode für diesen Artikel auf GitHub verfügbar.

Java unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs