5

Napotkaliśmy nieoczekiwany brak sprawdzania uprawnień bitowych w ochronie wiosennej. Chcielibyśmy potwierdzić, czy jest to oczekiwane zachowanie, a jeśli tak, jaka jest historia i/lub uzasadnienie tego.acl zabezpieczeń sprężynowych nie porównuje bitowych uprawnień

Używamy wtyczki grails spring-security-acl-1.1.1 która używa spring-security-acl 3.0.7.RELEASE.

destylowany scenariusz tego, co staramy się wiąże obiekt z ACL takich że aclUtilService.readAcl (obj) Zwraca ról udzielających:

PrincipalSid[sampleuser]; permission: BasePermission[...........................A....=16] 
GrantedAuthoritySid[ROLE_RWD]; permission: CumulativePermission[............................D.WR=11] 
GrantedAuthoritySid[ROLE_RW]; permission: CumulativePermission[..............................WR=3] 
GrantedAuthoritySid[ROLE_R]; permission: BasePermission[...............................R=1] 

Następnie oczekujemy, by sprawdzić dla pojedynczego pozwolenia jak napisać i zlecić return true. Wygląda jednak na to, że nie jest to obsługiwane. Na przykład, dla użytkownika, który ma wszystkie role zdefiniowane w obiekcie powyżej, wykonanie:

READ?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, BasePermission.READ)} 
WRITE?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, BasePermission.WRITE)} 
DELETE?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, BasePermission.DELETE)} 
READ-WRITE?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, new BasePermission(BasePermission.READ.getMask() | BasePermission.WRITE.getMask()))} 

Zwraca wyjściowa:

READ?: true 
WRITE?: false 
DELETE?: false 
READ-WRITE?: true 

Podczas gdy spodziewamy wszystko to aby wróciły prawdziwe . Spojrzeliśmy na źródło widzimy uprawnienie jest ostatecznie sprawdzane w AclImpl, który zawiera linię

if ((ace.getPermission().getMask() == p.getMask()) && ace.getSid().equals(sid)) { 

co wyjaśnia, dlaczego tylko dokładne maski są dopasowane.

Zmiana tylko ten wiersz jest nieco zaangażowania i odkryliśmy, że na wiosnę-security-ACL 3.1 kod ten został refactored aby umożliwić zgody udzielającej strategię być zdefiniowanym https://jira.spring.io/browse/SEC-1166

Jednak domyślna strategia udzielania nadal tylko sprawdza dokładnie maskę. A więc:

  • Dlaczego domyślna strategia grantu nie sprawdza maski bitowe? Jaki jest sens CumulativePermission, jeśli nie należy tego sprawdzać?
  • Jakie jest preferowane podejście do obsługi uprawnień bitowych, czy niepoprawnie konfigurujemy uprawnienia, czy też powinniśmy po prostu sprawdzić implementację bitowego sprawdzania uprawnień (i w takim przypadku, jaki jest preferowany sposób wykonania tego).

Dzięki za wszelkie wyjaśnienia lub wskazówki.

+0

Dodałem komentarz do https://jira.spring.io/browse/SEC-1166, który zakłada rozwiązanie olifernas do przyjęcia przez Spring Security. –

Odpowiedz

2

Bardzo mnie to zaskoczyło, gdy tworzyłem wtyczkę. Wydawało się bardzo dziwne, aby udawać, że używasz bitowego maskowania, a na koniec ogranicz się tylko do 32 uprawnień (chociaż powinno to wystarczyć dla większości aplikacji). Zobacz tę JIRA dla eksplanacji Ben Alexa: https://jira.spring.io/browse/SEC-1140

+0

Dzięki Burt, SEC-1140 wyjaśnia całkowicie sytuację i uzasadnienie. Wygląda na to, że powszechne zamieszanie wynika z posiadania projektu, który wygląda jak maskowanie, ale domyślne zachowanie nie wykorzystuje tego. Dla każdego, kto czyta to w przyszłości, opcje w tej sytuacji wydaje się być: * Używaj wielu odrębnych wpisów BasePermission zamiast CumulativePermission. * Użyj przynajmniej spring-security-acl 3.1 i zapewnić niestandardową strategię porównywania. –

+0

Mała modyfikacja Spring DefaultPermissionGrantingStrategy, która wykonuje porównanie maski bitowej. https://gist.github.com/oliverfernandez/36846fcdc03696a7b829 Co sądzisz? – oliferna

Powiązane problemy