Zarządzanie uprawnieniami w aplikacji webowej

Zarządzanie uprawnieniami w aplikacji webowej
BL
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

Cześć,
w jaki sposób obsługujecie w aplikacjach webowych uprawnienia użytkowników? Przykładowo mogę nadać użytkownikowi dla każdego modułu uprawnienie do wyświetlania, dodawania, edycji, usuwania. Uprawnienia te musiałyby być sprawdzane zarówno po stronie front-endowej jak i back-endowej. Pobranie listy uprawnień przy logowaniu i cachowanie ma swoje minusy, po pierwsze po zmianie uprawnienia wymagany jest relogin, po drugie trzymanie takiego cache przy dużej ilości userow będzie powodowało zużycie RAM'u. Lepszym sposobem będzie napisanie metody która będzie przy każdym requescie sprawdzać czy user ma dane uprawnienie? to znowu wiąże się z każdorazowym strzałem do DB w każdym endpoincie.
Macie może jakieś pomysły? Jak obsługujecie tego typu sytuacje?

SA
  • Rejestracja:około 12 lat
  • Ostatnio:25 minut
  • Postów:1431
0

Prosta autoryzacja moze byc zrobiona w middleware per request, zeby ograniczyc ilosc strzalow do bazy mozna robic cache z inwalidacją przy zmianie uprawnień. Poza tym lepiej nie wymyślaj koła na nowo tylko skorzystaj z tego co jest dostarczone. Jeśli chces trzymać uwierzytelnianie i autoryzację u siebie to np. ASP .NET Core Identity. Alternatywnie użyj czegoś zewnętrznego, Keycloack, Azure AD, Auth0, Okta itp.

BL
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

Nie mówię o uwierzytelnieniu, tylko o uprawnieniach zalogowanego użytkownika, wywołując jakąś metodę np. Save() chce sprawdzić czy użytkownik ma uprawnienie do Save danego obiektu, a kolejno uprawnienia do konkretnych obiektów, do jakichś części portalu itp. Dodam że działam na dość starej DB i muszę się do niej dostosować (pobieranie listy uprawnień).

edytowany 1x, ostatnio: blane
WeiXiao
  • Rejestracja:około 9 lat
  • Ostatnio:około 7 godzin
  • Postów:5108
0

Pobranie listy uprawnień przy logowaniu i cachowanie ma swoje minusy, po pierwsze po zmianie uprawnienia wymagany jest relogin, po drugie trzymanie takiego cache przy dużej ilości userow będzie powodowało zużycie RAM'u.

A ilu masz userów na raz lub dziennie w tej appce?

edytowany 1x, ostatnio: WeiXiao
S9
  • Rejestracja:ponad 4 lata
  • Ostatnio:około 2 lata
  • Lokalizacja:Warszawa
  • Postów:1092
3

Pobranie listy uprawnień przy logowaniu i cachowanie ma swoje minusy, po pierwsze po zmianie uprawnienia wymagany jest relogin, po drugie trzymanie takiego cache przy dużej ilości userow będzie powodowało zużycie RAM'u. Lepszym sposobem będzie napisanie metody która będzie przy każdym requescie sprawdzać czy user ma dane uprawnienie? to znowu wiąże się z każdorazowym strzałem do DB w każdym endpoincie.

Ja wiem że C# to nie Java, ale odpaliłem sobie napisany w Javie kod który wygenerował HashMapę zawierają Stringa jako klucza i kolekcję z 3 Stringami jako wartość z milionem elementów, wyszłoże taka mapa waży 320 mb. A ile ramu mają serwery?


edytowany 2x, ostatnio: scibi_92
BL
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

Już mniejsza o to ile mają RAMu i ile to będzie zajmować, liczyłem że może ktoś ma jakieś lepsze rozwiązanie, takie cachowanie ma też inny minus, jeśli user ma zapisane credentiale - (jest stale zalogowany) to zmiana uprawnień wymagałaby ponowne zainicjalizowanie takiej mapy uprawnień, cache. Więc musiała by być gdzieś dodatkowo zapisana informacje że trzeba zrobić ponową inicjalizację niestety tego już nie zapewnię w starych aplikacjach które są nadal w użytku.

CF
  • Rejestracja:ponad 4 lata
  • Ostatnio:około 2 lata
  • Postów:27
0

@blane: nie jestem pewien czy dobrze rozumiem problem?

Na froncie nie musisz mieć cache praw, w każdym response możesz wysłać aktualną listę praw albo nawet zrobić na to osobny endpoint. Te dane mogą być brane z cache w backendzie, żadnego strzału do bazy nie potrzebujesz.

W backendzie również nie ma żadnego problemu aby w momencie zmiany uprawnień (dodanie nowej roli) poza strzałem do bazy od razu aktualizować cache. Nie rozumiem, w którym momencie jeżeli user jest zalogowany musiałbyś cokolwiek przebudować czy od nowa mapować.

Oczywiście wtedy porzucasz czytanie praw bezpośrednio z Claimów, ale zawsze możesz sobie to obsłużyć dodając nowe Policy z własnymi IAuthorizationRequirementem i AuthorizationHandlerem, gdzie sobie możesz odczytać prawo z dowolnego miejsca.

BL
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

No ale muszę wiedzieć kiedy taki cache zaktualizować, jeśli uprawnienia zostaną zmienione w innej aplikacji to nie będę wiedział, że coś się zmieniło. O tym "IAuthorizationRequirementem i AuthorizationHandlerem" muszę poczytać bo nie wiem co to.

CF
  • Rejestracja:ponad 4 lata
  • Ostatnio:około 2 lata
  • Postów:27
1

@blane: ok, czyli problemem tak naprawdę jest informacja, że nie wiesz kiedy uprawnienia się zmieniają. Masz gdzieś tam jakiegoś Redisa? Jak tak to zacznij pytać o prawa przez niego, wtedy Keyspace Notifications powie Ci kiedy aktualizować swój lokalny cache, albo w ogóle nie będziesz potrzebował lokalnego cache bo Redis da radę spokojnie to obsłużyć.

Jeżeli nie chcesz Redisa albo nie możesz to czy masz możliwość postawienia serwis pośredniczącego przed bazą danych? Taki serwis mógłby przechwycić każde zapytanie do bazy danych ze zmianą uprawnień, zrobić sobie z tego cache i wystawić notify/subscribe a zapytanie popchnąć dalej. Czyli coś co by po prostu zrobiło Redisową protezę :)

Wtedy taki serwis poinformuje każdy dowolny inny serwis, że musi sobie zaktualizować konkretny wpis w cache.

A jeżeli masz po prostu wolną bazkę/nie chce Ci się bawić z notify/subscribe to po prostu uderzaj do serwisu pośredniczącego za każdym razem. Powinno wyjść lepiej niż robić zapytanie bezpośrednio do bazy.

Zakładam, że masz tych zapytań sporo na sekundę skoro nie chcesz uderzać bezpośrednio do bazki. W jednym projekcie uderzanie o prawa szło do bazki kilka razy na request, wtedy wystarczyło zrobić sobie małą klasę scoped, która to cachowała na czas requestu.

Możesz też zrobić cache gdzie trzymasz informację przez 10-20 sekund czy ile tam biznes pozwoli. Jeżeli użytkownik w te 10-02 sekund robi 2-3 requesty to zrobisz jeden call do bazy zamiast trzech. W cache nie musisz mieć wszystkich danych wszystkich userów, możesz trzymać tylko te aktywne w ciągu ostatnich 10 sekund.

Jeżeli zapytanie na bazie muli to może jest problem z zapytaniem?

edytowany 1x, ostatnio: CosmoFire
S9
  • Rejestracja:prawie 11 lat
  • Ostatnio:2 dni
  • Postów:123
0

Przy starcie apki ładujesz listę uprawnień do cache. Po drugie to zapinasz uprawnienia na daną rolę użytkownika, żeby móc tym w jakikolwiek sposób zapanować, przy dużej ilości użytkowników nie możesz sobie pozwolić na customowe konfigurowanie uprawnien. Po zmianie uprawnień dla danej roli robisz inwalidacje. Przy dużej ilość użytkowników ram to będzie twoje najmniejsze zmartwienie.

edytowany 1x, ostatnio: sharper_99
JU
  • Rejestracja:około 22 lata
  • Ostatnio:około miesiąc
  • Postów:5042
0

A czemu nie chcesz tego zrobić w taki sposób np (uproszczony pseudokod):

Kopiuj
public IActionResult Save()
{
  if(!loggedUser.HasRight(Rights.Save, "Documents"))
    return Unauthorized();
}

Gdzie HasRight to może być jakiś extension, który sprawdzi uprawnienia w bazie danych.

BL
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

Nie powiedziałem, że nie chcę do tej pory tak robiłem, tylko uprawnienia przy logowaniu wpadały w cache. Strzały po uprawnienie do DB mnie przerażają trochę, bo user klika po aplikacji otwiera okno za oknem a tu za każdym razem leci strzał :P Ale teraz tak myślę czy właśnie nie wprowadzić jakiegoś reloadingu uprawnien w tle w końcu one aż tak często się nie będą zmieniały.

G1
  • Rejestracja:około 4 lata
  • Ostatnio:4 dni
  • Postów:506
0

Ja nie widzę nic złego w strzałach do bazy po uprawnienia.

AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 16 godzin
  • Postów:973
0

Wystąpił już problem z bazą danych? Jeśli nie to nie ma co za bardzo się przejmować dopóki nie masz kilkudziesięciu requestów na sekundę. Replika DB potem i też wystarczy. A cache to już w ogóle powinien do końca wystarczyć


Zdalna praca dla Senior Python Developerów --> PW
G1
  • Rejestracja:około 4 lata
  • Ostatnio:4 dni
  • Postów:506
0

Gdy wywołuję akcję kontrolera np. Save to wymagam odpowiedniej roli np. Admin i canUpdateUser. Inaczej dostaje 401. Role trzymam w bazie danych i tyle

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)