= Java Security Architecture =

Java-Programme laufen normalerweise in einer "Sandbox" ab. D.h. sie haben keinen kompletten Zugriff auf den Computer, auf dem sie laufen, sondern können nur innerhalb der Java-VM arbeiten. Der Zugriff auf lokale Ressourcen wie Dateien, Netzwerk, etc. geschieht über einen Security-Manager. Dieser ist normalerweise entsprechend der Sicherheitsanforderungen konfiguriert. Das heisst praktisch, daß Programme, die direkt (z.B. von der Konsole) gestartet werden, alles dürfen und daß Programme, die aus dem Web heraus gestartet werden (Applets oder JavaWebStart) erstmal nichts dürfen. Es gibt aber auch Umgebungen z.B. für Webanwendungen, wo mehrere Applikationen in einer VM laufen und jede eine eigene Security Policy haben kann.

Einige Dinge, die verboten sind, wie das Schreiben von beliebigen Dateien, ist auf den ersten Blick einsichtig. Über andere Dinge muss man etwas nachdenken. So ist z.B. ein Teil der Java Reflection API "verboten", weil man sonst zu viel über private Klassen erfahren könnte. Das macht bei Installationen z.B. in einem Webserver (TomcatUnterDebian) sehr wohl Sinn, ist bei einem JavaWebStart-Programm aber etwas übertrieben.

== Warum? ==

Warum muss man sich nun mit diesem Thema beschäftigen? Wer Programme entwickeln will, die er an andere weitergeben will, hat mit JavaWebStart ein sehr luxuriöses Werkzeug zur Verfügung. Auch Applets in Webseiten sind für den einen oder anderen Zweck sehr interessant. Ein normaler Benutzer möchte aber vielleicht kein Programm starten, das ihn vor dem Start warnt, das die Security Policy dafür ausser Kraft gesetzt werden muss. Nun muss man also wissen, was man in so einem Programm darf und was nicht. Ich selber habe ein Programm geschrieben, das eigentlich (dachte ich bisher) nichts böses tut. Dennoch kann ich es nicht ohne Freigabe der Permissions per Webstart starten. Dies habe ich nun vor, zu ändern. Aus diesem Grunde möchte ich mich mit der Konfiguration der Security Architektur aber insbesondere auch damit beschäftigen, wie man programmiert, ohne diese zu verletzen. Die dabei gewonnenen Erkenntnisse möchte ich auf dieser Seite auch anderen zur Verfügung stellen.

== Debugging am Beispiel ==

=== Symptome von Problemen ===

Im allgemeinen erhält man bei einer Applikation, die gegen die Sicherheitsrichtlinien verstößt, eine recht informative Meldung. Leider war das bei mir nicht so. Man muss damit rechnen, daß sogar einfach gar nix passiert. Gerne  läuft dabei auch noch ein Thread der Applikation weiter (den man dann von Hand killen muss). Gerade wenn man eine neue Webstart-Applikation frisch zusammengestellt hat, weiss man da erstmal gar nicht, wo das Problem nun überhaupt liegt.

=== Tip zum Debugging ===

Man kann mit dem Befehl "javaws" das Webstart von Hand starten und erhält das Webstart-Fenster. Im Menü wählt man "Bearbeiten -> Einstellungen". Auf der Registerkarte "erweitert" schaltet man alle Unterpunkte von "Debugging" ein und wählt unter Java-Konsole den Punkt "Konsole einblenden". Nun beendet man das javaws-Programm und versucht sein Glück erneut mit der "fehlerhaften" Applikation. Es sollte nun eine Java-Konsole aufgehen, in der eine Fehlermeldung steht. Das ist doch schonmal etwas hilfreicher als nix! :-)

=== Die "richtige" Lösung ===

Ich will hier nicht weitermachen, ohne darauf hingewiesen zu haben, was die offizielle Doku jetzt sagt: Wir müssen unsere JAR-Files signieren und dann den Signaturschlüssel entweder vorher beim Benutzer installieren oder ihn beim ersten Start bestätigen lassen, das er uns traut. Aber das will ich ja eben vermeiden - Der Benutzer braucht mir nicht zu trauen, weil ich gar nichts unsicheres tun will. Weshalb ich an dieser Stelle weiterforsche...

=== Erste Lösung: Die Brechstange ===

Die Permissions, die eine Applikation haben darf, sind in Policy-Files niedergeschrieben. javaws hat eine solche Datei, um seine Grundeinstellungen festzulegen. Also ändern wir die mal und sehen, was passiert. Dazu fügen wir der Datei ''jre/lib/security/javaws.policy'' im JRE-Verzeichnis (z.B. ''/usr/lib/j2sdk1.5-sun/'') folgendes an:

  grant {
        permission java.security.AllPermission;
  };

Nun läuft mein Programm erstmal weiter. Natürlich kann das nicht die dauernde Lösung sein, aber wir können uns jetzt erstmal darauf verlassen, das unser Programm überhaupt per WS läuft (oder noch ein paar Fehlerchen beseitigen, wie ich das tun musste).

=== Zweite Lösung: Fehler finden ===

Nachdem wir nun wissen, ob unser Programm grundsätzlich läuft (oder ob wir erst noch andere Probleme lösen müssen), kommt es nun darauf an, die verbliebenen Policy-Verstöße zu finden und ggf. zu beseitigen. Um das tun zu können, benötigen wir eine "alles-Verbieten-Policy" in unserer Entwicklungsumgebung. Dazu erzeuge ich ein (leeres) File "policy" im Root-Verzeichnis meines Projektes. Dann rufe ich in Eclipse die "run configuration" auf und für auf der Registerkarte "Arguments" folgendes als VM-Argument ein:

  -Djava.security.manager -Djava.security.policy=policy

Wenn ich nun das Programm starte, bricht es mit der bekannten ~RuntimePermission-Exception ab. Nun habe ich aber den Vorteil, Eclipse zu haben und kann in Ruhe den Debugger benutzen um herauszufinden, was da los ist und wie ich die Aufgabe evtl. anders implementieren kann. Interessant zu wissen ist, daß Policy-Verstöße teilweise nicht gelten, wenn sie von der Java Runtime-Bibliothek begangen werden. So kann man z.B. die Methoden aus dem Paket java.beans benutzen, um Bean-Properties auszulesen, obwohl man den Namen der getter-Methode vorher nicht kennt. Versucht man dies mit Introspection hinzubekommen, gibt das eine ~RuntimePermission-Exception. Man darf nämlich nicht einfach in fremde Klassen hineinschauen. Auf den zweiten Blick also ganz logisch...

Was mich ein wenig ärgert ist die Tatsache, daß der Zugriff auf Annotations wohl immer eine "~RuntimePermission accessDeclaredMembers"-Permission verletzt. Damit hat sich die Arbeit mit Annotations wohl erledigt. Dahinter steht wohl sowas wie der Gedanke: "Wenn der Programmierer nichts böses vorhat und alle Klassen von ihm selber kommen, wofür braucht der dann noch Introspektion, er kennt doch eh alles!". Kann ich nicht ganz nachvollziehen, wofür dann überhaupt Annotations eingeführt wurden, aber vielleicht kommt mir ja noch die Erkenntnis, das ich mich hier getäuscht habe und alles doch ganz anders ist... :-)



==Links==

Ein paar Links zur Erklärung des Themas:

* [http://java.sun.com/j2se/1.5.0/docs/guide/security/spec/security-spec.doc.html Security Spezifikation] - ausführlichste Beschreibung zum Thema
* [http://java.sun.com/javase/6/docs/technotes/guides/deployment/deployment-guide/security.html Security Guide] - bester Startpunkt, um anzufangen
* [http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html Default Policy Implementation] - erklärt policy Files und deren Syntax

[{Tag Java}]