Stellen Sie sich eine GrantedAuthority als "Erlaubnis" oder "Recht" vor. Diese "Berechtigungen" werden (normalerweise) als Zeichenfolgen (mit der getAuthority()
Methode) ausgedrückt . Mit diesen Zeichenfolgen können Sie die Berechtigungen identifizieren und Ihre Wähler entscheiden, ob sie Zugriff auf etwas gewähren.
Sie können Benutzern verschiedene GrantedAuthoritys (Berechtigungen) erteilen, indem Sie sie in den Sicherheitskontext stellen. Normalerweise implementieren Sie dazu Ihren eigenen UserDetailsService, der eine UserDetails-Implementierung zurückgibt, die die erforderlichen GrantedAuthorities zurückgibt.
Rollen (wie sie in vielen Beispielen verwendet werden) sind nur "Berechtigungen" mit einer Namenskonvention, die besagt, dass eine Rolle eine GrantedAuthority ist, die mit dem Präfix beginnt ROLE_
. Mehr gibt es nicht. Eine Rolle ist nur eine GrantedAuthority - eine "Erlaubnis" - ein "Recht". In der Frühlingssicherheit sehen Sie viele Stellen, an denen die Rolle mit ihrem ROLE_
Präfix speziell behandelt wird, z. B. im RoleVoter, wo das ROLE_
Präfix standardmäßig verwendet wird. Auf diese Weise können Sie die Rollennamen ohne ROLE_
Präfix angeben . Vor Spring Security 4 wurde dieser spezielle Umgang mit "Rollen" nicht sehr konsequent befolgt, und Behörden und Rollen wurden häufig gleich behandelt (wie Sie zhasAuthority()
hasRole()
). Mit Spring Security 4 ist die Behandlung von Rollen konsistenter und Code, der sich mit "Rollen" (wie dem RoleVoter
, dem hasRole
Ausdruck usw.) befasst, fügt immer das ROLE_
Präfix für Sie hinzu. Bedeutet hasAuthority('ROLE_ADMIN')
also dasselbe wie hasRole('ADMIN')
weil das ROLE_
Präfix automatisch hinzugefügt wird. Weitere Informationen finden Sie im Migrationshandbuch für Federsicherheit 3 bis 4 .
Aber dennoch: Eine Rolle ist nur eine Autorität mit einem speziellen ROLE_
Präfix. In Spring ist Sicherheit 3 @PreAuthorize("hasRole('ROLE_XYZ')")
dasselbe wie @PreAuthorize("hasAuthority('ROLE_XYZ')")
und in Spring ist Sicherheit 4 @PreAuthorize("hasRole('XYZ')")
dasselbe wie @PreAuthorize("hasAuthority('ROLE_XYZ')")
.
In Bezug auf Ihren Anwendungsfall:
Benutzer haben Rollen und Rollen können bestimmte Vorgänge ausführen.
Sie könnten sich GrantedAuthorities
für die Rollen entscheiden, zu denen ein Benutzer gehört, und für die Vorgänge, die eine Rolle ausführen kann. Die GrantedAuthorities
für die Rollen haben das Präfix ROLE_
und die Operationen haben das Präfix OP_
. Ein Beispiel für Behörden Betrieb könnte sein OP_DELETE_ACCOUNT
, OP_CREATE_USER
, OP_RUN_BATCH_JOB
usw. können Rollen sein ROLE_ADMIN
, ROLE_USER
, ROLE_OWNER
usw.
Möglicherweise werden Ihre Entitäten GrantedAuthority
wie in diesem Beispiel (Pseudocode) implementiert :
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@ManyToMany
private final List<Operation> allowedOperations = new ArrayList<>();
@Override
public String getAuthority() {
return id;
}
public Collection<GrantedAuthority> getAllowedOperations() {
return allowedOperations;
}
}
@Entity
class User {
@Id
private String id;
@ManyToMany
private final List<Role> roles = new ArrayList<>();
public Collection<Role> getRoles() {
return roles;
}
}
@Entity
class Operation implements GrantedAuthority {
@Id
private String id;
@Override
public String getAuthority() {
return id;
}
}
Die IDs der Rollen und Operationen , die Sie in Ihrer Datenbank erstellen würde die GrantedAuthority Darstellung, zB ROLE_ADMIN
, OP_DELETE_ACCOUNT
usw. Wenn ein Benutzer authentifiziert wird, stellen Sie sicher , dass alle GrantedAuthorities aller seiner Rollen und die entsprechenden Operationen werden von den UserDetails.getAuthorities () zurück Methode.
Beispiel: Die Admin - Rolle mit der ID ROLE_ADMIN
hat die Operationen OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
ihm zugeordneten. Die Benutzerrolle mit ID ROLE_USER
hat die Operation OP_READ_ACCOUNT
.
Wenn ein Admin - Protokolle in der resultierenden Sicherheitskontext werden die GrantedAuthorities haben:
ROLE_ADMIN
, OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
,OP_RUN_BATCH_JOB
Wenn ein Benutzer meldet es, wird es:
ROLE_USER
,OP_READ_ACCOUNT
Der UserDetailsService würde dafür sorgen, dass alle Rollen und alle Operationen dieser Rollen erfasst und durch die Methode getAuthorities () in der zurückgegebenen UserDetails-Instanz verfügbar gemacht werden.
hasRole('xyz')
In Spring Security 4 wird erwartet, dass Sie das Präfix ROLE_ haben, während das PräfixhasAuthority('xyz')
nicht erwartet und genau bewertet, was übergeben wird. Ich habe diese Lösung verwendet, bin aberhasRole('OP_MY_PERMISSION')
seitdem auf Probleme gestoßen der ROLE_ Präfix benötigt wurde. Stattdessen hätte ich das verwenden sollen,hasAuthority('OP_MY_PERMISSION')
da ich das Präfix nicht hatte.<sec:authorize access="hasRole('ADMIN')">
dasselbe wie<sec:authorize access="hasRole('ROLE_ADMIN')">
AFAIK GrantedAuthority und Rollen sind in der Frühlingssicherheit gleich. Die getAuthority () - Zeichenfolge von GrantedAuthority ist die Rolle (gemäß Standardimplementierung SimpleGrantedAuthority).
Für Ihren Fall können Sie hierarchische Rollen verwenden
Nicht das genaue Sol, das Sie suchen, aber ich hoffe, es hilft
Bearbeiten : Auf Ihren Kommentar antworten
Rolle ist wie eine Erlaubnis in der Frühlingssicherheit. Die Verwendung von Intercept-URL mit hasRole bietet eine sehr genaue Kontrolle darüber, welche Operation für welche Rolle / Berechtigung zulässig ist.
In unserer Anwendung definieren wir die Berechtigung (dh die Rolle) für jede Operation (oder Ruhe-URL) für z. B. view_account, delete_account, add_account usw. Anschließend erstellen wir logische Profile für jeden Benutzer wie admin, guest_user, normal_user. Die Profile sind nur logische Gruppierungen von Berechtigungen, unabhängig von der Federsicherheit. Wenn ein neuer Benutzer hinzugefügt wird, wird ihm ein Profil zugewiesen (mit allen zulässigen Berechtigungen). Wenn ein Benutzer versucht, eine Aktion auszuführen, wird die Berechtigung / Rolle für diese Aktion mit den vom Benutzer gewährten Berechtigungen verglichen.
Außerdem verwendet der Standard-RoleVoter das Präfix ROLE_, sodass jede Berechtigung, die mit ROLE_ beginnt, als Rolle betrachtet wird. Sie können dieses Standardverhalten ändern, indem Sie ein benutzerdefiniertes RolePrefix im Rollenwähler verwenden und es in der Frühlingssicherheit verwenden.
quelle
Eine andere Möglichkeit, die Beziehung zwischen diesen Konzepten zu verstehen, besteht darin, eine ROLLE als Container von Behörden zu interpretieren.
Behörden sind detaillierte Berechtigungen, die auf eine bestimmte Aktion abzielen, manchmal verbunden mit einem bestimmten Datenumfang oder Kontext. Beispielsweise kann Lesen, Schreiben, Verwalten verschiedene Berechtigungsstufen für einen bestimmten Informationsbereich darstellen.
Außerdem werden die Behörden tief im Verarbeitungsablauf einer Anforderung durchgesetzt, während die ROLLE nach dem Anforderungsfilter gefiltert wird, bevor sie den Controller erreichen. Best Practices schreiben die Implementierung der behördlichen Durchsetzung hinter dem Controller in der Geschäftsschicht vor.
Andererseits sind ROLES eine grobkörnige Darstellung einer Reihe von Berechtigungen. Ein ROLE_READER hätte nur Lese- oder Anzeigeberechtigung, während ein ROLE_EDITOR sowohl Lese- als auch Schreibberechtigung hätte. Rollen werden hauptsächlich für ein erstes Screening am Rande der Anforderungsverarbeitung verwendet, z. B. http. ... .antMatcher (...). hasRole (ROLE_MANAGER)
Die Behörden, die tief im Prozessablauf der Anforderung durchgesetzt werden, ermöglichen eine feinkörnigere Anwendung der Berechtigung. Beispielsweise kann ein Benutzer über die Berechtigung zum Lesen und Schreiben verfügen, um eine Ressource auf der ersten Ebene zu speichern, jedoch nur zum Lesen in eine Unterressource. Ein ROLE_READER würde sein Recht einschränken, die Ressource der ersten Ebene zu bearbeiten, da er die Schreibberechtigung zum Bearbeiten dieser Ressource benötigt, aber ein @ PreAuthorize-Interceptor könnte seinen Versuch blockieren, die Unterressource zu bearbeiten.
Jake
quelle
Wie andere bereits erwähnt haben, stelle ich mir Rollen als Container für detailliertere Berechtigungen vor.
Obwohl ich festgestellt habe, dass die Implementierung der Hierarchierolle keine genaue Kontrolle über diese detaillierten Berechtigungen hat.
Deshalb habe ich eine Bibliothek erstellt, um die Beziehungen zu verwalten und die Berechtigungen als erteilte Berechtigungen in den Sicherheitskontext einzufügen.
Möglicherweise verfügt die App über eine Reihe von Berechtigungen, z. B. CREATE, READ, UPDATE, DELETE, die dann der Rolle des Benutzers zugeordnet sind.
Oder spezifischere Berechtigungen wie READ_POST, READ_PUBLISHED_POST, CREATE_POST, PUBLISH_POST
Diese Berechtigungen sind relativ statisch, aber die Beziehung der Rollen zu ihnen kann dynamisch sein.
Beispiel -
Sie können APIs erstellen, um die Beziehung dieser Berechtigungen zu einer Rolle zu verwalten.
Ich möchte keine weitere Antwort kopieren / einfügen. Hier ist der Link zu einer vollständigeren Erklärung zu SO.
https://stackoverflow.com/a/60251931/1308685
Um meine Implementierung wiederzuverwenden, habe ich ein Repo erstellt. Bitte zögern Sie nicht, einen Beitrag zu leisten!
https://github.com/savantly-net/spring-role-permissions
quelle