Spring Security mit Rollen und Berechtigungen

77

Ich versuche, rollenbasierte Sicherheit mit Berechtigungen einzurichten. Ich versuche dies zusammen mit Spring-Security zu tun.

Ich möchte ACL nicht einrichten, da dies anscheinend ein Overkill für meine Anforderungen ist.

Ich möchte nur einfache Berechtigungen und Rollen haben, wie in diesem Artikel beschrieben . Leider beschreibt der Artikel nicht, wie die angegebene Lösung implementiert werden soll.

Hat das schon jemand versucht und kann mich in die richtige Richtung weisen? Vielleicht gibt es einen anderen Blogeintrag, der die Implementierung beschreibt?

Vielen Dank.

Blitz
quelle
15
Für alle, die hier ankommen, gibt es einen Artikel, der genau mein Problem löst. Bitte werfen Sie einen Blick darauf
Flash
Ich habe diesen Artikel gelesen und versuche das umzusetzen. Würden Sie mir bitte sagen, wie Sie diese SpringSecurityDaoImpl-Klasse implementiert haben? @PreAuthorize beeinflusst meine URLs überhaupt nicht! Ich habe genau das Material in diesem Artikel gemacht.
Sina
@sina Sie müssen die SpringSecurityDaoImplJust-Erweiterung nicht JdbcDaoImplwie im Beispiel implementieren . Schauen Sie sich unbedingt den Beispielcode auf github an, auf den im Artikel verwiesen wird.
Flash

Antworten:

32

Um dies umzusetzen, müssen Sie anscheinend:

  1. Erstellen Sie Ihr Modell (Benutzer, Rolle, Berechtigungen) und eine Möglichkeit, Berechtigungen für einen bestimmten Benutzer abzurufen.
  2. Definieren Sie Ihre eigenen org.springframework.security.authentication.ProviderManagerund konfigurieren Sie sie (stellen Sie ihre Anbieter ein) auf eine benutzerdefinierte org.springframework.security.authentication.AuthenticationProvider. Dieser letzte sollte auf seiner Authentifizierungsmethode eine Authentifizierung zurückgeben, die mit den org.springframework.security.core.GrantedAuthorityin Ihrem Fall allen Berechtigungen für den angegebenen Benutzer abgerechnet werden sollte .

Der Trick in diesem Artikel besteht darin, Benutzern Rollen zuzuweisen, aber die Berechtigungen für diese Rollen im Authentication.authoritiesObjekt festzulegen.

Zu diesem Zweck empfehle ich Ihnen, die API zu lesen und zu prüfen, ob Sie einige grundlegende ProviderManager und AuthenticationProvider erweitern können, anstatt alles zu implementieren. Ich habe das mit dem org.springframework.security.ldap.authentication.LdapAuthenticationProviderFestlegen eines benutzerdefinierten LdapAuthoritiesPopulators gemacht, der die richtigen Rollen für den Benutzer abruft.

Hoffe diesmal habe ich bekommen was du suchst. Viel Glück.

ezequielb
quelle
1
Erweitern Sie diesen DaoAuthenticationProvider und geben Sie ihm einen benutzerdefinierten UserDetailsService, der das Laden der Berechtigungen durchführen soll.
Ezequielb
78

Ich bin der Autor des betreffenden Artikels.

Zweifellos gibt es mehrere Möglichkeiten, dies zu tun, aber ich implementiere normalerweise eine benutzerdefinierte Methode UserDetails, die sich mit Rollen und Berechtigungen auskennt. Roleund Permissionsind nur benutzerdefinierte Klassen, die Sie schreiben. (Nichts Besonderes - Rolehat einen Namen und eine Reihe von PermissionInstanzen und Permissioneinen Namen.) Dann getAuthorities()gibt das GrantedAuthorityObjekt Objekte zurück, die so aussehen:

PERM_CREATE_POST, PERM_UPDATE_POST,PERM_READ_POST

anstatt Dinge wie zurückzugeben

ROLE_USER, ROLE_MODERATOR

Die Rollen sind weiterhin verfügbar, wenn Ihre UserDetailsImplementierung über eine getRoles()Methode verfügt. (Ich empfehle einen zu haben.)

Im Idealfall weisen Sie dem Benutzer Rollen zu und die zugehörigen Berechtigungen werden automatisch ausgefüllt. Dies würde einen Benutzer beinhalten UserDetailsService, der weiß, wie diese Zuordnung durchgeführt wird, und alles, was er tun muss, ist, die Zuordnung aus der Datenbank zu beziehen . (Siehe Artikel für das Schema.)

Anschließend können Sie Ihre Berechtigungsregeln in Bezug auf Berechtigungen anstelle von Rollen definieren.

Hoffentlich hilft das.


quelle
1
Hallo, könnten Sie bitte eine praktische Lösung für benutzerdefinierte Benutzerdetails bereitstellen, wie Sie in dieser Antwort beschrieben haben? Vielen Dank.
Rayman
Hallo, ich habe eine Anwendung mit Spring Security mithilfe einer benutzerdefinierten AuthenticationProvider- und UserDetailsService-Klasse implementiert. Jetzt möchte ich Rollen und Berechtigungen in meiner Anwendung verwenden. Ich verwende jetzt Folgendes : @Secured ("ROLE_ADMIN") , das nur Handles-Rollen verwendet. Wie ich dies erweitere, um mit den Berechtigungen umzugehen. (Weitere Details hier -> stackoverflow.com/questions/23072619/… )
Kleber Mota
6

Die grundlegenden Schritte sind:

  1. Verwenden Sie einen benutzerdefinierten Authentifizierungsanbieter

    <bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton">
    ...
    </bean>
    

  2. Lassen Sie Ihren benutzerdefinierten Anbieter eine benutzerdefinierte UserDetailsImplementierung zurückgeben. Dies UserDetailsImplwird getAuthorities()wie folgt aussehen:

    public Collection<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>();
        for (GrantedAuthority role: roles) {
            permissions.addAll(getPermissionsIncludedInRole(role));
        }
        return permissions;
    }
    

Natürlich können Sie von hier aus viele Optimierungen / Anpassungen für Ihre spezifischen Anforderungen vornehmen.

gpeche
quelle
5

Dies ist der einfachste Weg, dies zu tun. Ermöglicht Gruppenberechtigungen sowie Benutzerberechtigungen.

-- Postgres syntax

create table users (
  user_id serial primary key,
  enabled boolean not null default true,
  password text not null,
  username citext not null unique
);

create index on users (username);

create table groups (
  group_id serial primary key,
  name citext not null unique
);

create table authorities (
  authority_id serial primary key,
  authority citext not null unique
);

create table user_authorities (
  user_id int references users,
  authority_id int references authorities,
  primary key (user_id, authority_id)
);

create table group_users (
  group_id int references groups,
  user_id int referenecs users,
  primary key (group_id, user_id)
);

create table group_authorities (
  group_id int references groups,
  authority_id int references authorities,
  primary key (group_id, authority_id)
);

Dann in META-INF / applicationContext-security.xml

<beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder" />

<authentication-manager>
    <authentication-provider>

        <jdbc-user-service
                data-source-ref="dataSource"

                users-by-username-query="select username, password, enabled from users where username=?"

                authorities-by-username-query="select users.username, authorities.authority from users join user_authorities using(user_id) join authorities using(authority_id) where users.username=?"

                group-authorities-by-username-query="select groups.id, groups.name, authorities.authority from users join group_users using(user_id) join groups using(group_id) join group_authorities using(group_id) join authorities using(authority_id) where users.username=?"

                />

          <password-encoder ref="passwordEncoder" />

    </authentication-provider>
</authentication-manager>
Neil McGuigan
quelle
1

Nur der Vollständigkeit halber (vielleicht muss es nicht jemand anderes von Grund auf neu implementieren):

Wir haben wie alle anderen unsere eigene kleine Bibliothek implementiert. Es soll die Dinge einfacher machen, damit unsere Entwickler es nicht jedes Mal neu implementieren müssen. Es wäre großartig, wenn die Federsicherheit rbac sofort unterstützen würde, da dieser Ansatz viel besser ist als der auf Standardberechtigungen basierende.

Schauen Sie sich Github (OSS, MIT-Lizenz) an , um festzustellen , ob es Ihren Anforderungen entspricht. Im Grunde geht es nur um die Zuordnung von Rollen- <-> Berechtigungen. Das fehlende Teil, das Sie selbst bereitstellen müssen, ist im Grunde die Zuordnung der <-> Benutzerrollen, z. B. durch Zuordnen von Gruppen (racf / Anzeigengruppen) zu Rollen (1: 1) oder durch Implementieren einer zusätzlichen Zuordnung. Das ist in jedem Projekt anders, daher ist es nicht sinnvoll, eine Implementierung bereitzustellen.

Wir haben dies grundsätzlich intern verwendet, damit wir von Anfang an mit rbac beginnen können. Wir können es später noch durch eine andere Implementierung ersetzen, wenn die Anwendung wächst, aber es ist wichtig, dass wir das Setup gleich zu Beginn erhalten.

Wenn Sie rbac nicht verwenden, besteht eine gute Chance, dass die Berechtigungen über die gesamte Codebasis verteilt sind und Sie später Schwierigkeiten haben, diese (in Rollen) zu extrahieren / zu gruppieren. Die generierten Grafiken helfen auch dabei, später darüber nachzudenken / sie neu zu strukturieren.

Alexander Pilch
quelle
1

ACL war auch für meine Anforderungen übertrieben. Am
Ende habe ich eine Bibliothek ähnlich der von @ Alexander erstellt, um eine GrantedAuthorityListe für Rolle-> Berechtigungen basierend auf der Rollenmitgliedschaft eines Benutzers einzufügen.

Beispiel: Verwenden einer Datenbank zum Speichern der Beziehungen -

@Autowired 
RolePermissionsRepository repository;

public void setup(){
  String roleName = "ROLE_ADMIN";
  List<String> permissions = new ArrayList<String>();
  permissions.add("CREATE");
  permissions.add("READ");
  permissions.add("UPDATE");
  permissions.add("DELETE");
  repository.save(new RolePermissions(roleName, permissions));
}

Wenn ein Authentifizierungsobjekt in die aktuelle Sicherheitssitzung eingefügt wird, verfügt es über die ursprünglichen Rollen / erteilten Berechtigungen.

Diese Bibliothek bietet 2 integrierte Integrationspunkte für Spring Security. Wenn der Integrationspunkt erreicht ist, wird der PermissionProvider aufgerufen, um die effektiven Berechtigungen für jede Rolle abzurufen, in der der Benutzer Mitglied ist.
Die eindeutige Liste der Berechtigungen wird als GrantedAuthority-Elemente im Authentifizierungsobjekt hinzugefügt.

Sie können beispielsweise auch eine benutzerdefinierte PermissionProviderMethode implementieren , um die Beziehungen in der Konfiguration zu speichern.

Eine ausführlichere Erklärung finden Sie hier - https://stackoverflow.com/a/60251931/1308685

Und der Quellcode ist hier - https://github.com/savantly-net/spring-role-permissions

Jeremy
quelle
0

Nach dem Lesen dieses Beitrags aus Baeldung. Ich fand, dass die Lösung ziemlich einfach ist.

Was ich getan habe, ist das Hinzufügen der Rolle und Berechtigungen zur GrantedAuthority. Ich konnte auf beide Methoden hasRole () und hasAuthority () zugreifen.

Gil Nz
quelle