Autorisierung in RCP-Anwendungen

Im Gegensatz zu den im Plug-in-Manifest deklarierten Aktionen gibt es hier jedoch keine Möglichkeit, auf die in der Oberfläche dargestellten Elemente zuzugreifen und diese gegebenenfalls zu deaktivieren. Als Lösung bietet sich das dynamische Deinstallieren von Plug-ins zur Laufzeit an. Dazu wird die zu berechtigende Komponente (Perspektive, Wizard,.) in ein eigenes Plug-in ausgegliedert. Beim Starten der Anwendung werden dann alle erforderlichen Berechtigungen überprüft, und gegebenenfalls wird das zugehörige Plug-in deinstalliert.

Die Durchführung der Berechtigungsprüfung erfolgt in der Einstiegsklasse der RCP-Applikation. Diese wird im Plug-in-Manifest durch den Erweiterungspunkt org.eclipse.core.runtime.applications festgelegt. Die dort angegebene Klasse muss das Interface org.eclipse.core.runtime.IPlatformRunnable implementieren. In der Methode run(Object) erfolgt zunächst die Authentifizierung des Anwenders sowie die Berechtigungsprüfung und das Deinstallieren der Plug-ins, bevor die Workbench schließlich gestartet wird. In Listing 3 ist die Berechtigungsprüfung und das Deinstallieren von Plug-ins exemplarisch für den Erweiterungspunkt org.eclipse.ui.newWizards dargestellt.

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;

public class MyApplication implements IPlatformRunnable {
    /* (non-Javadoc)
     * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)
     */
    public Object run(Object args) throws Exception {
        Display display = PlatformUI.createDisplay();
        try {
            if (!AccessControl.login()) {
                return IPlatformRunnable.EXIT_OK;
            }
            try {
                checkWizardPermissions();
            } catch (BundleException e) {
                return IPlatformRunnable.EXIT_OK;
            }
            int returnCode = PlatformUI.createAndRunWorkbench(
                    display, new ApplicationWorkbenchAdvisor());
            if (returnCode == PlatformUI.RETURN_RESTART) {
                return IPlatformRunnable.EXIT_RESTART;
            }
            return IPlatformRunnable.EXIT_OK;
        } finally {
            display.dispose();
        }
    }
    
    /**
     * Check permissions for new wizards
     * 
     * @throws BundleException if an error occurs
     */
    private void checkWizardPermissions() throws BundleException {
        IExtensionRegistry registry = Platform.getExtensionRegistry();
        IExtensionPoint extensionPoint = 
                registry.getExtensionPoint("org.eclipse.ui.newWizards");
        for (IExtension extension : extensionPoint.getExtensions()) {
            for (IConfigurationElement element 
                    : extension.getConfigurationElements()) {
                if ("wizard".equals(element.getName())) {
                    String id = element.getAttribute("id");
                    if (!AccessControl.hasPermission(id)) {
                        Bundle bundle = Platform.getBundle(
                                extension.getContributor().getName());
                        bundle.stop();
                        bundle.uninstall();
                        break;
                    }
                }
            }
        }
    }
} 

Alle Erweiterungspunkte sind in einer zentralen Registratur hinterlegt, auf die mit der statischen Methode getExtensionRegistry()der Klasse Platform zugegriffen werden kann. Unter Angabe der ID erhält man mithilfe der Methode getExtensionPoint(String) einen bestimmten Erweiterungspunkt. Dieser liefert über getExtensions()alle registrierten Erweiterungen (Implementierungen zum Erweiterungspunkt). Für die Erweiterungen können die im Plug-in-Manifest definierten Konfigurationselemente und deren Attribute abgefragt werden (Abb. 5). Für die Berechtigungsprüfung dient die ID der Erweiterung, in diesem Fall die ID des Wizards, als Schlüssel.

Abb. 5: Konfigurationselement mit Attributen

Zum Deinstallieren wird das zugehörige Bundle benötigt, das mit Platform.getBundle(String) abgefragt werden kann. Dieses wird dann zunächst durch Aufruf von stop()angehalten und anschließend durch uninstall()deinstalliert. Alle in diesem Plug-in definierten Erweiterungen sind anschließend in der Applikation nicht mehr verfügbar.

Fazit

Die Eclipse Rich Client Platform stellt umfangreiche Funktionalitäten zur Verfügung, die einfach verwendet werden können. Weichen die Anforderungen jedoch vom Standardverhalten ab, so ist häufig ein nicht unerheblicher Aufwand erforderlich, um die RCP an die eigenen Bedürfnisse anzupassen. Mit den dargestellten Konzepten steht jedoch eine flexible Lösung zur Anwender-abhängigen Berechtigung von Funktionen innerhalb von RCP-Applikationen zur Verfügung. Aktionen können sowohl im Quellcode als auch im Plug-in-Manifest angelegt und berechtigt werden. Ein Nachteil bei der Definition im Plug-in-Manifest ist allerdings, dass die zugehörigen Plug-ins bereits beim Starten der Anwendung geladen werden müssen. Durch die Deinstallation von Plug-ins lassen sich beliebige Funktionen berechtigen, die im Plug-in-Manifest als Erweiterungen definiert sind. Dazu ist lediglich eine Aufteilung der Funktionen auf einzelne Plug-ins erforderlich.
Die hier dargestellten Konzepte wurden im Rahmen eines konkreten Projekts erarbeitet und implementiert, um die dort gestellten Anforderungen abzudecken. Es sind jedoch auch andere Konzepte zur Autorisierung denkbar (z.B. über den Eclipse Activity-/Capability-Mechanismus).

Michael Buchholz arbeitet als Software-Entwickler und Projektleiter bei der Bredex GmbH in Braunschweig. Kontakt: Michael.Buchholz@bredex.de

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.