Spring Security i uprawnienia

Spring Security i uprawnienia
ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Witajcie,
Mam problem z uprawnieniami użytkowników w Spring Security. Wiem jak sprawdzić za pomocą wyrażenia springa czy użytkownik jest w danej grupie (np. ROLE_ADMIN), ale czy istnieje możliwość sprawdzenia czy użytkownik ma konkretną permisję - np. PERM_addingposts. Bazę danych mam już w ten sposób zaprojektowaną, zastanawia mnie tylko jak sprawdzić czy ma permisję za pomocą wyrażeń springa, ponieważ hasRole() chyba powinno służyć do sprawdzania grupy, nie poszczególnych uprawnień

SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:616
0

@PreAuthorize

SE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 4 lata
  • Postów:21
0

Tak jak wyżej, tylko żeby móc z tego skorzystać, to trzeba sobie w global-method-securityustawić flagępre-post-annotations="enabled"

TK
  • Rejestracja:ponad 13 lat
  • Ostatnio:4 dni
  • Postów:342
0

Mozesz uzyc wyrazenia hasPermission

ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Tak, chodziło mi o coś takiego jak hasPermission. Nie rozumiem tylko dlaczego tutaj jest hasPermission(#id, 'RouteRemove').
http://stackoverflow.com/questions/16164615/preauthorize-with-haspermission-executes-code-twice
Czym jest to #id?

TK
  • Rejestracja:ponad 13 lat
  • Ostatnio:4 dni
  • Postów:342
0

Parametrem metody. Nie chce mi sie czytac calego wpisu na SO ale jest tam napisane cos o tym, ze sa jakies trasy (route) i uzytkownik moze skasowac trase tylko wtedy kiedy jest jej wlascicielem. Jak mozna sie domyslec ustala sie kto jest wlascicielem danej trasy na podstawie identyfikatora (parametr id).

Pewnie dlatego jest tam napisane hasPermission(#id, 'RouteRemove') co znaczy mniej wiecej tyle co "sprawdz czy ktos ma uprawnienia do usuniecia trasy na podstawie identyfikatora, ktorego wartosc przechowywana jest w parametrze id danej metody).

SE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 4 lata
  • Postów:21
0

To #id odwołuje się w tym przykładzie do tego pola @PathVariable("id") Integer id , sprawdzasz po prostu czy użytkownik ma "przyzwolenie" RouteRemove dla danego id

EDIT:

dokładnie to co napisał @tk wyżej

edytowany 1x, ostatnio: setsudanhana
ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Mam obiekt User, który implementuje UserDetailsService i jego instancja przechowywana jest jako principal. Jak mam do niego uzyskać dostęp z poziomu tego wyrażenia i w której metodzie muszę zwrócić listę uprawnień?

SE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 4 lata
  • Postów:21
0

Możesz sobie dopisać takiego ControllerAdvice:

Kopiuj
@ControllerAdvice
public class UserControllerAdvice {
 
    @ModelAttribute
    public User currentUser(Authentication authentication) {
        if (null != authentication){
            return (User) authentication.getPrincipal();
        }
        return null;
    }
} 

Wtedy do parametrów funkcji dopisujesz

@ModelAttribute User user
, i jest on tam wtedy wstrzykiwany.

ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Rozumiem, ale w takim przypadku za każdym razem będę musiał go również umieszczać w modelu (tak żeby plik jsp miał do niego dostęp). Korzystam z tagów springa security, gdzie jest to znacznie łatwiejsze.
Reasumując. Co musi implementować User, żebym mógł wykonać na nim hasPermission? Dalej nie rozumiem o co chodzi z tym #id. Przecież User na którym wykonane ma być to hasPermission powinien wynikać z kontekstu, tak jak to jest w przypadku hasRole

edytowany 1x, ostatnio: Zaprogramowany
TK
  • Rejestracja:ponad 13 lat
  • Ostatnio:4 dni
  • Postów:342
1
Zaprogramowany napisał(a):

Co musi implementować User, żebym mógł wykonać na nim hasPermission?

Jezeli wyraziles sie poprawnie w poprzednim poscie i User implementuje interfejs UserDetailsService to moim zdaniem w ogole nie powinienes wywolywac na nim wyrazenia hasPermission.

Inaczej sprawa wyglada w przypadku gdy User to klasa reprezentujaca konkretnego uzytkownika, ktora wcale nie implementuje interfejsu UserDetailsService (moze implementowac interfejs UserDetails) tylko cos co implementuje UserDetailsService zwraca obiekt klasy User. Wtedy ma to jakis sens.

Innymi slowy: jezeli wspomniales o interfejsie UserDetailsService to pewnie masz klase, ktora go implementuje. Jezeli tak jest to zwroc uwage na to, ze interfejs UserDetailsService posiada metode loadUserByUsername, ktora zwraca obiekt implementujacy interfejs UserDetails.

Ta metoda moze zwrocic Twoja wlasna klase, ale moze tez zwrocic klase org.springframework.security.core.userdetails.User, ktora implementuje interfejs UserDetails. Konstruktor tej klasy posiada parametr z kolekcja uprawnien i tam mozesz wlasnie przydzielic uzytkownikowi jakies tam zezwolenia.

Zaprogramowany napisał(a):

Dalej nie rozumiem o co chodzi z tym #id. Przecież User na którym wykonane ma być to hasPermission powinien wynikać z kontekstu, tak jak to jest w przypadku hasRole

OK, to moze inaczej: wyobraz sobie, ze tworzysz serwis internetowy gdzie uzytkownicy wrzucaja jakies pliki. Kazdy uzytkownik ma mozliwosc usuniecia dowolnego pliku pod warunkiem, ze jest to plik umieszczony przez niego - nie mozna kasowac plikow innym uzytkownikom. Zalozmy tez, ze wszelkie niezbedne informacje o plikach przechowujesz w tabeli bazy danych - kazdy plik ma swoj identyfikator w postaci klucza podstawowego.

Co w takiej sytuacji zrobisz? Zapewne napiszesz sobie usluge, w ktorej znajdzie sie metoda:

Kopiuj
 
public void deleteFile(Long id);

Powyzsza metoda usunie plik o identyfikatorze id (w praktyce moze to byc cos innego niz id, np. encja). Tylko, ze te metode wywoluje nie tylko Zdzisia ale takze Marysia. Jak Zdzisia bedzie cwana i podmieni identyfikator (np. w adresie strony) to usunie zdjecie Marysi. Marysia w tym momencie kontaktuje sie z Toba i drze ryja na caly regulator bo przeciez nie po to robila przez pol godziny dziubek do lustra, zeby zazdrosna Zdzisia usunela jej jakze wazne zdjecie.

Aby tego uniknac nalezy sprawdzic nie tylko czy uzytkownik posiada uprawnienia usuwania plikow ale takze czy jest upowazniony do usuniecia akurat tego a nie innego zasobu. Dlatego wlasnie przed metoda deleteFile napiszesz sobie cos w stylu:

Kopiuj
 
@PreAuthorize("hasPermission(#id, 'DeleteFile')")
public void deleteFile(Long id);

Wtedy jezeli Zdzisia wywola te metode, to zanim dojdzie do usuniecia pliku zostanie wykonana logika sprawdzajaca czy ten plik nalezy do Zdzisi. Logike sprawdzania wlasciciela pliku mozesz zawrzec w dowolnej klasie, ktora implementuje interfejs PermissionEvaluator - zostanie tam przekazany rozdzaj uprawnien oraz identyfikator. Musisz tylko w swojej konfiguracji dodac tego Twojego evaluatora do listy evaluatorow - jezeli Twoja konfiguracja dziedziczy po GlobalMethodSecurityConfiguration to mozesz uzyc metody setPermissionEvaluator.

ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Mój błąd, chodziło o UserDetails. Rozumiem :D Dzięki za tak obszerną wypowiedź. Gdybym chciał zrobić to samo na hasRole, to musiałbym dodać jeszcze sprawdzanie czy to zdjęcie należy do konkretnego Usera, a tu wszystko dzieje się w PermissionEvaluator.

ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Jeszcze jedno pytanko :) gdybym wykonywał hasPermission z poziomu pliku JSP, to wyglądało by było to tak? hasPermission(principal, 'addpost')? Czy w jaki sposób odwołać się do principal?

TK
  • Rejestracja:ponad 13 lat
  • Ostatnio:4 dni
  • Postów:342
1

Technologia JSP nigdy nie bylem jakos szczegolnie zainteresowany wiec nie wiem, ale wydaje mi sie ze propozycja użytkownika @setsudanhana jest calkiem ok - mozesz napisac ControllerAdvice, ktory doda do modelu interesujace Cie dane.

To nie jest tez tak, ze bedziesz musial za kazdym razem dodawac jakies dane do modelu. Dane beda dodawane automatycznie poniewaz ControllerAdvice moze dzialac dla wszystkich kontrolerow. Dodanie danych do modelu nie powinno tez wykluczac mozliwosci uzywania wyrazen Springa. Innymi slowy: piszesz jednego ControlerAdvice'a, ktory dodaje principala do modelu i pozniej sobie w dowolnym widoku tego principala uzywasz.

Ponadto dostep do principala moze miec takze PermissionEvaluator, wiec nie zawsze jest sens umieszczania go w wyrazeniu. W Twoim przypadku to bym rozwazyl czy nie lepiej jest napisac po prostu hasPermission(null, 'addpost') o ile posty nie sa jakos powiazane np. z kategoria. Bo jezeli sa to wtedy hasPermission(category, 'addpost'). PermissionEvaluator sobie wtedy pobierze tego principala sam. No ale to taka moja koncepcja, niekoniecznie jedynie sluszna.

edytowany 2x, ostatnio: tk
ZA
  • Rejestracja:około 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:174
0

Dzięki za pomoc, już nie mam żadnych wątpliwości :) Zabieram się do pisania

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)