Różnica między rolą a GrantedAuthority w Spring Security

Istnieją koncepcje i implementacje w zabezpieczeniach Springa, takie jak Interfejs GrantedAuthority, Aby uzyskaćuprawnienia do autoryzacji/kontroli dostępu.

Chciałbym, aby to dopuszczalne operacje, takie jak createSubUsers , lub deleteAccounts , które pozwoliłbym admin (z rolą ROLE_ADMIN).

Zaczynam się mylić jako tutoriale / dema, które widzę w Internecie. Staram się połączyć to, co czytam, ale myślę, że traktujemy te dwa zamiennie.

I see hasRole consuming a GrantedAuthority string? Zdecydowanie robię to źle w zrozumieniu. Co to są koncepcyjnie w Spring Security?

Jak przechowywać rolę użytkownika, niezależnie od władz dla tej roli?

Patrzę również na Interfejs org.springframework.security.core.userdetails.UserDetails, który jest używany w uwierzytelnianiu-provider, do którego odwołuje się DAO, który zużywa User (uwaga Last GrantedAuthority):

public User(String username, 
            String password, 
            boolean enabled, 
            boolean accountNonExpired,
            boolean credentialsNonExpired, 
            boolean accountNonLocked, 
            Collection<? extends GrantedAuthority> authorities)

Czy jest jakiś inny sposób na rozróżnienie pozostałe dwie? A może nie jest wspierany i musimy tworzyć własne?

Author: nbro, 2013-10-22

3 answers

Myśl o GrantedAuthority jako o "pozwoleniu" lub "prawie". Te "uprawnienia" są (normalnie) wyrażane jako ciągi znaków (za pomocą metody getAuthority()). Te ciągi pozwalają zidentyfikować uprawnienia i pozwolić głosującym zdecydować, czy przyznają dostęp do czegoś.

Możesz przyznać różne Grantedauthitys (uprawnienia) użytkownikom, 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 wymagane uprawnienia.

Role (ponieważ są używane w wielu przykładach) są po prostu "uprawnieniami" z konwencją nazewnictwa, która mówi, że rola jest GrantedAuthority, która zaczyna się od prefiksu ROLE_. Nic więcej. Rola to tylko Grantauthority - "pozwolenie" - "prawo". W spring security widać wiele miejsc, w których rola z prefiksem ROLE_ jest obsługiwana specjalnie jak np. w Rolevoterze, gdzie prefiks ROLE_ jest używany jako domyślny. Pozwala to na podaj nazwy ról bez prefiksu ROLE_. Przed Spring security 4, Ta specjalna obsługa " ról " nie była przestrzegana bardzo konsekwentnie, a władze i role były często traktowane tak samo (jak widać np. w implementacji metody hasAuthority() W SecurityExpressionRoot - która po prostu wywołuje hasRole()). W Spring Security 4 traktowanie ról jest bardziej spójne i kod, który zajmuje się "rolami" (jak wyrażenie RoleVoter, hasRole itp.) zawsze dodaje ROLE_ prefiks dla Ciebie. Więc hasAuthority('ROLE_ADMIN') oznacza to samo co hasRole('ADMIN') ponieważ prefiks ROLE_ jest dodawany automatycznie. Więcej informacji można znaleźć w przewodniku migracji spring security 3 do 4 .

Ale nadal: rola jest tylko autorytetem ze specjalnym prefiksem ROLE_. Tak więc w Spring security 3 @PreAuthorize("hasRole('ROLE_XYZ')") jest tym samym co @PreAuthorize("hasAuthority('ROLE_XYZ')"), a w Spring security 4 @PreAuthorize("hasRole('XYZ')") jest tym samym co @PreAuthorize("hasAuthority('ROLE_XYZ')").

W odniesieniu do twojego przypadku użycia:

Użytkownicy mają role i role mogą wykonywać pewne szef.

Możesz skończyć w GrantedAuthorities dla ról, do których należy użytkownik i operacji, które może wykonać. GrantedAuthorities dla ról ma prefiks ROLE_, a operacje mają prefiks OP_. Przykładem władz operacyjnych może być OP_DELETE_ACCOUNT, OP_CREATE_USER, OP_RUN_BATCH_JOBitd. Rolami mogą być ROLE_ADMIN, ROLE_USER itp.

Może skończyć się, że Twoje podmioty zaimplementują GrantedAuthority jak w tym (pseudo-kodzie) przykładzie:

@Entity
class Role implements GrantedAuthority {
    @Id
    private String id;

    @OneToMany
    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;

    @OneToMany
    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 Utwórz w swojej bazie danych reprezentację GrantedAuthority, np. "ROLE_ADMIN", "OP_DELETE_ACCOUNT" itp. Gdy użytkownik jest uwierzytelniony, upewnij się, że wszystkie przyznane organy wszystkich jego ról i odpowiadające im operacje są zwracane z UserDetails.metoda getauthority ().

Przykład: Rola administratora o id ROLE_ADMIN ma przypisane do niej operacje OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB. Rola użytkownika o id ROLE_USER ma operację OP_READ_ACCOUNT.

Jeśli administrator loguje się w wynikowym kontekście bezpieczeństwa będzie miał: ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB

Jeśli użytkownik go zarejestruje, będzie miał: ROLE_USER, OP_READ_ACCOUNT

UserDetailsService dba o to, aby zebrać wszystkie role i wszystkie operacje tych ról i udostępnić je za pomocą metody getauthority() w zwracanej instancji UserDetails.

 264
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-02 09:30:54

AFAIK GrantedAuthority i role są takie same w Spring security. GrantedAuthority łańcuch getAuthority() jest rolą (zgodnie z domyślną implementacją SimpleGrantedAuthority).

W Twoim przypadku możesz użyć ról hierarchicznych

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    <constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
        class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_ADMIN > ROLE_createSubUsers
            ROLE_ADMIN > ROLE_deleteAccounts 
            ROLE_USER > ROLE_viewAccounts
        </value>
    </property>
</bean>

Nie dokładnie sol, którego szukasz, ale mam nadzieję, że to pomoże

Edit : Odpowiedz na twój komentarz

Rola jest jak pozwolenie w spring-security. korzystanie z intercept-url z hasRole zapewnia bardzo drobnoziarnistą kontrolę tego, co operacja jest dozwolona dla której roli/uprawnienia.

Sposób obsługi w naszej aplikacji jest taki, że definiujemy uprawnienia (tj. rolę) dla każdej operacji (lub rest url) dla np. view_account, delete_account, add_account itp. Następnie tworzymy profile logiczne dla każdego użytkownika, takie jak admin, guest_user, normal_user. Profile są po prostu logicznym grupowaniem uprawnień, niezależnym od spring-security. Po dodaniu nowego użytkownika przypisany jest do niego profil (posiadający wszystkie dopuszczalne uprawnienia). Now when ever użytkownik próbuje wykonać jakąś akcję, uprawnienie / rola dla tej akcji jest sprawdzana przed uprawnieniami użytkownika.

Również defaultn RoleVoter używa prefiksu 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 RolePrefix w roli wyborcy I używając go w zabezpieczeniach spring.

 7
Author: coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 13:15:28

Innym sposobem zrozumienia relacji między tymi pojęciami jest interpretacja roli jako pojemnika władz.

Organy są drobnoziarnistymi 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.

Również władze są egzekwowane głęboko w przepływie przetwarzania żądania, podczas gdy ROLE są filtrowane przez żądanie filtruj sposób przed dotarciem do kontrolera. Najlepsze praktyki nakazują egzekwowanie przepisów przez organy poza administratorem w warstwie biznesowej.

Z drugiej strony, role są gruboziarnistą reprezentacją zbioru uprawnień. Role_reader miałby tylko uprawnienia do odczytu lub podglądu, podczas gdy ROLE_EDITOR miałby zarówno odczyt, jak i zapis. Role są wykorzystywane głównie do pierwszego przeglądu Na Zewnątrz przetwarzania wniosków, takich jak http. ... .antMatcher(...).hasRole(ROLE_MANAGER)

Organy egzekwowane głęboko w przepływie procesu żądania pozwalają na dokładniejsze stosowanie uprawnień. Na przykład użytkownik może mieć uprawnienia do Odczytu Zapisu do pierwszego poziomu zasobu, ale tylko do odczytu do zasobu podrzędnego. Posiadanie ROLE_READER ograniczyłoby jego prawo do edycji zasobu pierwszego poziomu, ponieważ potrzebuje uprawnień do zapisu, aby edytować ten zasób, ale @ Preautoryzuj interceptor może zablokować jego wstępną edycję zasobu podrzędnego.

Jake

 1
Author: softjake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-14 23:13:00