Pomyśl o GrantedAuthority jako o „pozwoleniu” lub „prawie”. Te „uprawnienia” są (normalnie) wyrażone jako ciągi znaków (za pomocągetAuthority()
metody). Te ciągi pozwalają zidentyfikować uprawnienia i pozwalają wyborcom zdecydować, czy przyznają dostęp do czegoś.
Można przyznać użytkownikom różne GrantedAuthority (uprawnienia), umieszczając je w kontekście bezpieczeństwa. Zwykle robisz to, implementując własną usługę UserDetailsService, która zwraca implementację UserDetails, która zwraca potrzebne GrantedAuthorities.
Role (jak są używane w wielu przykładach) są po prostu „uprawnieniami” z konwencją nazewnictwa, która mówi, że rolą jest GrantedAuthority, która zaczyna się od przedrostka ROLE_
. Nic więcej. Rolą jest po prostu GrantedAuthority - „pozwolenie” - „prawo”. Widzisz wiele miejsc w zabezpieczeniach wiosennych, w których rola z jej ROLE_
prefiksem jest obsługiwana specjalnie, jak np. W RoleVoter, gdzie ROLE_
prefiks jest używany domyślnie. Pozwala to na podanie nazw ról bez ROLE_
prefiksu. Przed Spring Security 4 ta specjalna obsługa „ról” nie była przestrzegana bardzo konsekwentnie, a uprawnienia i role były często traktowane tak samo (jak np. Można zobaczyć w implementacji hasAuthority()
metody whasRole()
). Ze sprężyną Security 4, leczenie ról jest bardziej spójna i kod, który zajmuje się „ról” (jak RoleVoter
The hasRole
wyrażenie itd) zawsze dodaje ROLE_
prefiks dla Ciebie. Więc hasAuthority('ROLE_ADMIN')
oznacza to samo co hasRole('ADMIN')
ponieważ ROLE_
prefiks zostanie dodany automatycznie. Więcej informacji można znaleźć w przewodniku migracji zabezpieczeń wiosennych 3 do 4 .
Ale nadal: rola jest tylko autorytetem ze specjalnym ROLE_
prefiksem. Tak więc na wiosnę bezpieczeństwo 3 @PreAuthorize("hasRole('ROLE_XYZ')")
jest takie samo, @PreAuthorize("hasAuthority('ROLE_XYZ')")
a na wiosnę bezpieczeństwo 4 @PreAuthorize("hasRole('XYZ')")
jest takie samo jak @PreAuthorize("hasAuthority('ROLE_XYZ')")
.
Jeśli chodzi o przypadek użycia:
Użytkownicy mają role i role mogą wykonywać określone operacje.
Możesz skończyć GrantedAuthorities
dla ról, do których należy użytkownik i operacji, które rola może wykonywać. GrantedAuthorities
Dla ról mają prefiks ROLE_
i operacje mają prefiks OP_
. Przykładem mogą być działania władz OP_DELETE_ACCOUNT
, OP_CREATE_USER
, OP_RUN_BATCH_JOB
itp Role mogą być ROLE_ADMIN
, ROLE_USER
,ROLE_OWNER
itd.
Może się zdarzyć, że twoje jednostki zaimplementują się GrantedAuthority
tak jak w tym (pseudo-kodzie) przykładzie:
@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;
}
}
Identyfikatory ról i operacji tworzonych w bazie danych będzie reprezentacja GrantedAuthority, np ROLE_ADMIN
,OP_DELETE_ACCOUNT
itd. Gdy użytkownik jest uwierzytelniony, upewnij się, że wszystkie GrantedAuthorities wszystkich swoich ról i odpowiadające im operacje są zwracane z UserDetails.getAuthorities () metoda.
Przykład: Administrator rolę id ROLE_ADMIN
ma operacje OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
przypisane do niego. Rola użytkownika o identyfikatorze ROLE_USER
ma operacjęOP_READ_ACCOUNT
.
Jeśli loguje admin w otrzymanej kontekście zabezpieczeń będzie mieć GrantedAuthorities:
ROLE_ADMIN
, OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
,OP_RUN_BATCH_JOB
Jeśli użytkownik loguje się, będzie to mieć
ROLE_USER
,OP_READ_ACCOUNT
UserDetailsService zadbałby o zebranie wszystkich ról i wszystkich operacji tych ról i udostępnienie ich za pomocą metody getAuthorities () w zwróconej instancji UserDetails.
hasRole('xyz')
w Wiosna Security 4 spodziewa się, aby mieć ROLE_ prefiks natomiasthasAuthority('xyz')
nie oczekuje prefiks i ocenia dokładnie to, co jest przekazywane w. Użyłem tego rozwiązania, ale został uruchomiony na problemy zhasRole('OP_MY_PERMISSION')
od ROLE_ była potrzebna prefiks. Zamiast tego powinienem był użyćhasAuthority('OP_MY_PERMISSION')
skoro nie miałem przedrostka.<sec:authorize access="hasRole('ADMIN')">
jest taki sam jak<sec:authorize access="hasRole('ROLE_ADMIN')">
AFAIK GrantedAuthority i role są takie same w wiosennym bezpieczeństwie. Rolą jest łańcuch getAuthority () GrantedAuthority (zgodnie z domyślną implementacją SimpleGrantedAuthority).
W twoim przypadku możesz użyć hierarchicznych ról
Nie dokładnie taki zol, którego szukasz, ale mam nadzieję, że to pomoże
Edytować : Odpowiedz na swój komentarz
Rola jest jak zezwolenie na wiosenne bezpieczeństwo. użycie intercept-url z hasRole zapewnia bardzo precyzyjną kontrolę nad tym, która operacja jest dozwolona dla jakiej roli / uprawnienia.
Sposób, w jaki obsługujemy naszą aplikację, definiujemy uprawnienia (tj. Rolę) dla każdej operacji (lub adresu URL) dla np. Konta_wyświetlania, konta_skasowania, konta_dodatkowego itp. Następnie tworzymy profile logiczne dla każdego użytkownika, np. Admin, użytkownik_użytkownika, użytkownik_zwykły. Profile to logiczne grupowanie uprawnień, niezależne od zabezpieczenia wiosennego. Po dodaniu nowego użytkownika zostaje do niego przypisany profil (posiadający wszystkie dozwolone uprawnienia). Teraz, gdy użytkownik próbuje wykonać jakąś akcję, uprawnienia / rola dla tej akcji są sprawdzane pod kątem przyznanego przez użytkownika uprawnienia.
Również domyślny RoleVoter używa przedrostka ROLE_, więc każdy organ zaczynający się od ROLE_ jest uważany za rolę, możesz zmienić to domyślne zachowanie, używając niestandardowego prefiksu RoleP w roli wyborca roli i używając go w zabezpieczeniach wiosennych.
źródło
Innym sposobem na zrozumienie związku między tymi pojęciami jest interpretacja ROLI jako kontenera organów.
Organy są drobiazgowymi uprawnieniami ukierunkowanymi na określone działanie połączone czasami z określonym zakresem danych lub kontekstem. Na przykład odczyt, zapis, zarządzanie mogą reprezentować różne poziomy uprawnień do danego zakresu informacji.
Ponadto uprawnienia są egzekwowane głęboko w przepływie przetwarzania żądania, podczas gdy rola jest filtrowana według filtru żądania przed dotarciem do kontrolera. Najlepsze praktyki zalecają wdrożenie organów ścigania poza Administratorem w warstwie biznesowej.
Z drugiej strony ROLE to gruboziarnista reprezentacja zestawu uprawnień. ROLE_READER miałby tylko uprawnienia do odczytu lub przeglądania, podczas gdy ROLE_EDITOR miałby zarówno odczyt, jak i zapis. Role są używane głównie do pierwszego przeglądu na obrzeżach przetwarzania żądania, takiego jak http. ... .antMatcher (...). hasRole (ROLE_MANAGER)
Egzekwowanie uprawnień przez władze w procesie przetwarzania wniosku pozwala na bardziej szczegółowe zastosowanie pozwolenia. Na przykład użytkownik może mieć uprawnienia do odczytu Zapis do pierwszego poziomu zasobu, ale tylko do odczytu do podrzędnego zasobu. Posiadanie ROLE_READER ograniczyłoby jego prawo do edytowania zasobu pierwszego poziomu, ponieważ potrzebuje on uprawnienia do zapisu do edycji tego zasobu, ale przechwytywacz @PreAuthorize może zablokować jego próbę edycji podrzędnego zasobu.
Jake
źródło
Jak wspomnieli inni, uważam role za kontenery dla bardziej szczegółowych uprawnień.
Chociaż zauważyłem, że implementacja roli hierarchii nie ma dokładnej kontroli nad tymi szczegółowymi uprawnieniami.
Stworzyłem więc bibliotekę do zarządzania relacjami i wstrzykiwania uprawnień jako nadane uprawnienia w kontekście bezpieczeństwa.
Mogę mieć zestaw uprawnień w aplikacji, np. UTWÓRZ, ODCZYTAJ, AKTUALIZUJ, USUŃ, które są następnie powiązane z rolą użytkownika.
Lub bardziej szczegółowe uprawnienia, takie jak READ_POST, READ_PUBLISHED_POST, CREATE_POST, PUBLISH_POST
Uprawnienia te są względnie statyczne, ale relacja ról z nimi może być dynamiczna.
Przykład -
Możesz tworzyć interfejsy API do zarządzania relacją tych uprawnień do roli.
Nie chcę kopiować / wklejać innej odpowiedzi, więc oto link do pełniejszego wyjaśnienia na temat SO.
https://stackoverflow.com/a/60251931/1308685
Aby ponownie użyć mojej implementacji, utworzyłem repozytorium. Prosimy o kontakt!
https://github.com/savantly-net/spring-role-permissions
źródło