2010-08-30 6 views
7

Ich habe Java EE 6 mit Glassfish v3.0.1 verwendet, und ich frage mich, ob Java EE-Sicherheitsmodell ACL unterstützt, und wenn ja, wie feinkörnig wird es?Unterstützt das Java EE-Sicherheitsmodell ACL?

EDITED
ich über Glassfish v3 Sicherheit mit jdbc Bereich implementieren, dass der Bereich zur Laufzeit Blick in der Tabelle USER in der Datenbank für die Authentifizierung zu überprüfen, indem am password Feld und Genehmigung der Suche nach im role Feld suchen . Das Rollenfeld enthält nur 2 entweder ADMINISTRATOR oder DESIGNER. Es handelt sich also um eine Eins-zu-Eins-Karte zwischen Benutzer und Rolle. Auf der Bohne Ebene verwaltet, ich implementiert diese

private Principal getLoggedInUser() 
{ 
    HttpServletRequest request = 
      (HttpServletRequest) FacesContext.getCurrentInstance(). 
       getExternalContext().getRequest(); 
    if(request.isUserInRole("ADMINISTRATORS")){ 
     admin = true; 
    }else{ 
     admin = false; 
    } 
    return request.getUserPrincipal(); 
} 

public boolean isUserNotLogin() 
{ 
    Principal loginUser = getLoggedInUser(); 
    if (loginUser == null) 
    { 
     return true; 
    } 
    return false; 
} 

public String getLoginUserName() 
{ 
    Principal loginUser = getLoggedInUser(); 
    if (loginUser != null) 
    { 
     return loginUser.getName(); 
    } 
    return "None"; 
} 

von isUserInRole nennen, kann ich feststellen, ob der Benutzer admin ist oder nicht, dann wird der JSF den Inhalt entsprechend render. Das ist aber nicht feinkörnig genug (echte schnelle Hintergrundinformation: Es gibt mehrere Projekte, ein Projekt enthält mehrere Zeichnungen). Denn wenn u eine DESIGNER sind, können Sie alle Zeichnungen aus allen Projekten sehen (was, wenn ich nur tom wollen A auf Projekt arbeiten, während peterB auf Projekt arbeiten, können Cindy über die beiden Projekt überwacht A und B). Ich möchte, dass ich zur Laufzeit beim Erstellen des Benutzers festlegen kann, welches Projekt er/sie sehen kann. Gibt es einen Weg, dies zu erreichen? HINWEIS: Es gibt mehr als nur zwei Projekte, das obige Beispiel dient nur zur Demonstration.

Antwort

5

Das Java EE-Sicherheitsmodell authentifiziert einen 'Principal', der möglicherweise über 'Rollen' verfügt.

In der anderen Dimension haben Sie Dienste und Ressourcen, die konfigurierbare 'Berechtigungen' oder 'Fähigkeiten' benötigen.

In der Konfiguration legen Sie fest, welche 'Principals' oder 'Rollen' welche 'Permissions' oder 'Capabilities' haben.

Mit anderen Worten, ja, es unterstützt ACL und es ist so feinkörnig, wie Sie es wollen, aber Sie müssen sich an die Terminologie gewöhnen.

In der Antwort von Vineet ist der ausgezeichnete Vorschlag, "Rollen" pro Projekt-ID zu erstellen. Da die Leute sowieso Projekten zugeordnet werden müssen, ist es einfach, die Leute zu diesen Zeitpunkten zu diesen Gruppen hinzuzufügen. Alternativ kann ein zeitgesteuertes Skript die Gruppenmitgliedschaften basierend auf den Rollen aktualisieren. Der letztere Ansatz kann vorzuziehen sein, da es einfacher ist, die Sicherheit zu überprüfen, wenn diese Entscheidungen an einer Stelle statt über den gesamten Verwaltungscode verteilt sind.

Alternativ können Sie "grobkörnige" Rollen verwenden, z. Designer und Nutzung der Datenbank (oder Programmlogik) machen die Ansichten für den Benutzer in

SELECT p.* FROM projects p, assignments a WHERE p.id = a.projectId AND a.finishdate < NOW(); 

oder

@Stateless class SomeThing { 

    @Resource SessionContext ctx; 

    @RolesAllowed("DESIGNER") 
    public void doSomething(Project project) { 
     String userName = ctx.getCallerPrincipal.getName(); 

     if (project.getTeamMembers().contains(userName) { 
      // do stuff 
     } 
    } 

} 

Beachten Sie, dass die grobkörnige Zugriffskontrolle hier angemeldet zu beschränken hat mit einer Anmerkung geschehen anstelle von Code. Dies kann viele schwierig zu testende Boilerplate aus dem Code verschieben und viel Zeit sparen.

Es gibt ähnliche Funktionen zum Rendern von Webseiten, bei denen Sie Teile des Bildschirms basierend auf dem aktuellen Benutzer mit einem Tag in der Regel rendern können.

Auch weil Sicherheit eine solche weitreichende Sorge ist, ich denke, es ist besser, die zur Verfügung gestellten Funktionen nutzen im Kontext zu bekommen, als eine Batterie von Booleschen Flags wie isAdmin um zu passieren, da dies schnell sehr chaotisch wird. Es erhöht die Kopplung und es ist eine andere Sache, die die Klassen schwieriger zum Komponententest macht.

In vielen JSF-Implementierungen gibt es Tags, die beim Rendern von optionalen Dingen helfen können. Hier ist, sind Beispiele für Richfaces und Naht:

<!-- richfaces --> 
<rich:panel header="Admin panel" rendered="#{rich:isUserInRole('admin')}"> 
    Very sensitive information 
</rich:panel> 

<!-- seam --> 
<h:commandButton value="edit" rendered="#{isUserInRole['admin']}"/>. 

Here is an article zu erklären, wie es

+0

Ich schrieb einige Codes mit jdbc Realm für die Sicherheit, aber es nur "Principal" verwenden, weiß ich nicht, wie man 'Berechtigungen' und' Fähigkeiten', glauben Sie, ich kann einige Codes, und fragen Sie nach Ihrer Meinung ? –

+0

Dies wird immer helfen, wenn nicht von mir, dann von mehr sachkundigen Menschen hier. –

+0

Ich habe gerade meinen Beitrag aktualisiert. Wenn es Ihnen nichts ausmacht, bitte führen Sie mich. Vielen Dank –

3

Die Java EE-Sicherheitsmodell implementiert RBAC (Role Based Access Control) zu ADF hinzuzufügen. Für einen Java EE-Programmierer bedeutet dies effektiv, dass Benutzern Berechtigungen für den Zugriff auf eine Ressource erteilt werden können. Ressourcen können Dateien, Datenbanken oder sogar Code enthalten. Daher ist es möglich, nicht nur den Zugriff auf Objekte wie Dateien und Tabellen in Datenbanken zu beschränken, es ist auch möglich, den Zugriff auf ausführbaren Code zu beschränken.

Jetzt können Berechtigungen in Rollen zusammengefasst werden, die schließlich mit Benutzern/Subjekten verknüpft sind. Dies ist das Java EE-Sicherheitsmodell auf den Punkt gebracht.

Aus der Beschreibung Ihres Problems scheint es, dass Sie zwischen zwei verschiedenen Projekten als zwei verschiedene Ressourcen unterscheiden möchten und daher entweder zwei separate Berechtigungsobjekte oder zwei separate Rollen haben, um dasselbe zu berücksichtigen. Da Sie bereits Rollen (besser als Benutzergruppen bezeichnet) wie Administrator, Designer usw. haben, ist dies in Java EE nicht ganz einfach zu erreichen. Der Grund dafür ist, dass Sie den Zugriff auf Ressourcen für Benutzer in einer Rolle basierend auf einer zusätzlichen Eigenschaft der Ressource - der Projekt-ID - unterscheiden. Dies fällt technisch in den Bereich, der als ABAC (Attribut Based Access Control) bekannt ist.

Eine Möglichkeit, ABAC in Java EE zu erreichen, besteht darin, die Eigenschaften/Attribute, die der Rolle erteilt wurden, im Rollennamen zu tragen. Also anstelle des folgenden Codes:

if(request.isUserInRole("DESIGNERS")){ 
    access = true; 
}else{ 
    access = false; 
} 

sollten Sie etwas wie folgt tun. Beachten Sie das Zeichen ":", das als Trennzeichen verwendet wird, um den Rollennamen vom zugehörigen Attribut zu unterscheiden.

if(request.isUserInRole("DESIGNERS"+":"+projectId)){ 
    access = true; 
}else{ 
    access = false; 
} 

Natürlich ist es der Teil, wo Sie Ihr Login-Modul geändert werden soll (entweder in der Konfiguration oder in Code) Rollen zurückkehrte Projekt-IDs enthalten, anstelle von einfachen Rollennamen. Beachten Sie, dass alle vorgeschlagenen Änderungen umfassend auf Probleme überprüft werden müssen. Beispielsweise sollte das Trennzeichen nicht Teil eines Rollennamens sein. Andernfalls ist es durchaus möglich, Zugriffsüberschreitungs-Angriffe auszuführen.

Wenn sich das oben genannte als eine Handvoll erweist, könnten Sie Systeme wie Shibboleth betrachten, die Unterstützung für ABAC bieten, obwohl ich nie gesehen habe, dass es in einer Java EE-Anwendung verwendet wird.

+0

Also, wenn der 'Designer' Berechtigungen für mehrere Projekte hat, dann denke ich, dass es etwas Parsing erfordert, aber ich denke, das ist keine große Sache. Aber ich bin mir nicht sicher, ob ich es verstehe, wenn Sie über "Privilege Escalation Attacks" sprechen. Ich dachte, dass die Rolle Namen Unterstützung wie folgt aussehen: 'DESIGNERS: 1234', aber dann sagte Sie, dass' man sollte das Trennzeichen nicht Teil eines Rollennamens sein '. Können Sie das bitte näher ausführen? –

+1

Wenn Sie die Erstellung von Rollen über die Anwendung zulassen, ist es wichtig sicherzustellen, dass die Rollennamen keine Sonderzeichen enthalten (in diesem Fall das Trennzeichen). Wenn der interne Rollenname (mit der Projekt-ID) beispielsweise DESIGNERS: 1234 lautet, dann würde der interne Rollenname DESIGNER: 1234: 5678 lauten, wenn Sie die Konstruktion des Rollennamens mit diesem Namen zulassen, aber Zugriff auf das Projekt 5678 haben . Abhängig davon, wie die Anwendung codiert ist, könnte es möglich sein, Zugang zu einer Person in einer solchen Rolle zu erhalten, um Zugang zu dem 1234-Projekt zu erhalten, wodurch eine Erhöhung der Privilegien erreicht wird. –

+0

hab es geschafft. Danke, ich werde das im Hinterkopf behalten –