Jestem zupełnie nowy w używaniu programu claims
in ASP.NETIdentity
i chcę poznać najlepsze praktyki w zakresie korzystania z Roles and/or Claims
.
Po całym tym czytaniu wciąż mam pytania w stylu ...
P: Czy nie używamy już ról?
P: Jeśli tak, dlaczego nadal oferowane są role?
P: Czy powinniśmy używać tylko roszczeń?
P: Czy powinniśmy używać razem ról i roszczeń?
Moja początkowa myśl jest taka, że „powinniśmy” używać ich razem. Widzę Claims
jako podkategorie do tych, Roles
które obsługują.
NA PRZYKŁAD:
Rola:
Roszczenia księgowe : CanUpdateLedger, CanOnlyReadLedger, CanDeleteFromLedger
P: Czy mają się wzajemnie wykluczać?
P: A może lepiej jest skorzystać TYLKO z roszczeniami i „w pełni się zakwalifikować”, jak twierdzi?
P: Więc jakie są tutaj najlepsze praktyki?
PRZYKŁAD: wspólne używanie ról i roszczeń
Oczywiście musiałbyś napisać własną logikę atrybutów dla tego ...
[Authorize(Roles="Accounting")]
[ClaimAuthorize(Permission="CanUpdateLedger")]
public ActionResult CreateAsset(Asset entity)
{
// Do stuff here
return View();
}
PRZYKŁAD: Pełne kwalifikowanie roszczeń
[ClaimAuthorize(Permission="Accounting.Ledger.CanUpdate")]
public ActionResult CreateAsset(Asset entity)
{
// Do stuff here
return View();
}
źródło
Odpowiedzi:
Rola to symboliczna kategoria, która gromadzi użytkowników, którzy mają te same poziomy uprawnień bezpieczeństwa. Autoryzacja oparta na rolach wymaga najpierw zidentyfikowania użytkownika, następnie ustalenia ról, do których jest on przypisany, a na końcu porównania tych ról z rolami, które mają uprawnienia dostępu do zasobu.
W przeciwieństwie do tego roszczenie nie jest oparte na grupie, a raczej na tożsamości.
z dokumentacji Microsoft :
Kontrola bezpieczeństwa może później określić prawo dostępu do zasobu na podstawie wartości jednego lub większej liczby roszczeń.
Państwo może używać zarówno w koncercie, lub użyć jednego rodzaju w pewnych sytuacjach, a druga w innych sytuacjach. Zależy to głównie od współpracy z innymi systemami oraz strategii zarządzania. Na przykład menedżerowi może być łatwiej zarządzać listą użytkowników przypisanych do roli niż zarządzać tym, kto ma przypisane określone roszczenie. Oświadczenia mogą być bardzo przydatne w scenariuszu zgodnym z REST, w którym można przypisać roszczenie do klienta, a klient może następnie przedstawić roszczenie do autoryzacji, zamiast przekazywać nazwę użytkownika i hasło dla każdego żądania.
źródło
Jak doskonale wyjaśnił @Claies, twierdzenia mogą być bardziej opisowe i stanowią głęboki rodzaj roli. Myślę o nich jako o twoich rolach. Mam identyfikator siłowni, więc należę do roli członków. Jestem również na lekcjach kickboxingu, więc mam dla nich prawo do kickboxingu. Moja aplikacja wymagałaby deklaracji nowej roli, aby pasowała do moich praw członkowskich. Zamiast tego mam identyfikatory dla każdej klasy grupy, do której należę, zamiast wielu nowych typów członkostwa. Dlatego twierdzenia pasują do mnie lepiej.
Jest świetny film wyjaśniający Barry'ego Dorransa, mówiący o przewadze używania twierdzeń nad rolami. Stwierdza również, że role są nadal w .NET w celu zapewnienia kompatybilności wstecznej. Film zawiera wiele informacji na temat sposobu działania roszczeń, ról, zasad, autoryzacji i uwierzytelniania.
Możesz go znaleźć tutaj: Autoryzacja ASP.NET Core z Barr Dorrans
źródło
Używając różnych technik uwierzytelniania i autoryzacji przez dziesięciolecia, moja obecna aplikacja MVC korzysta z następującej metodologii.
Oświadczenia są używane do wszystkich autoryzacji. Użytkownicy mają przypisaną jedną rolę (możliwych jest wiele ról, ale nie potrzebuję tego) - więcej poniżej.
Zgodnie z powszechną praktyką używana jest klasa atrybutu ClaimsAuthorize. Ponieważ większość akcji kontrolera to CRUD, mam procedurę w generowaniu bazy danych z pierwszym kodem, która iteruje wszystkie akcje kontrolera i tworzy typy oświadczeń dla każdego atrybutu akcji kontrolera odczytu / edycji / tworzenia / usuwania. Np. Z
[ClaimsAuthorize("SomeController", "Edit")] [HttpPost]
Do użycia w widoku MVC klasa kontrolera bazowego przedstawia elementy widoku torby
protected override void OnActionExecuting(ActionExecutingContext filterContext) { // get user claims var user = filterContext.HttpContext.User as System.Security.Claims.ClaimsPrincipal; if (user != null) { // Get all user claims on this controller. In this controler base class, [this] still gets the descendant instance type, hence name List<Claim> claims = user.Claims.Where(c => c.Type == this.GetType().Name).ToList(); // set Viewbag with default authorisations on this controller ViewBag.ClaimRead = claims.Any(c => c.Value == "Read"); ViewBag.ClaimEdit = claims.Any(c => c.Value == "Edit"); ViewBag.ClaimCreate = claims.Any(c => c.Value == "Create"); ViewBag.ClaimDelete = claims.Any(c => c.Value == "Delete"); } base.OnActionExecuting(filterContext); }
W przypadku menu witryny internetowej i innych działań niezwiązanych z administratorem mam inne zastrzeżenia. Np. Czy użytkownik może przeglądać określone pole pieniężne.
bool UserHasSpecificClaim(string claimType, string claimValue) { // get user claims var user = this.HttpContext.User as System.Security.Claims.ClaimsPrincipal; if (user != null) { // Get the specific claim if any return user.Claims.Any(c => c.Type == claimType && c.Value == claimValue); } return false; } public bool UserHasTradePricesReadClaim { get { return UserHasSpecificClaim("TradePrices", "Read"); } }
Więc gdzie pasują role?
Mam tabelę, która łączy rolę z (domyślnym) zestawem oświadczeń. Podczas ustawiania autoryzacji użytkownika domyślnie przypisuje się użytkownikowi roszczenia dotyczące jego roli. Każdy użytkownik może mieć więcej lub mniej roszczeń niż domyślne. Aby ułatwić edycję, lista oświadczeń jest wyświetlana według kontrolera i działań (w wierszu), a następnie są wyświetlane inne oświadczenia. Przyciski są używane z odrobiną JavaScript do wybierania zestawu działań minimalizujących „klikanie” wymagane przy wybieraniu roszczeń. Po zapisaniu roszczenia użytkowników są usuwane, a wszystkie wybrane roszczenia są dodawane. Aplikacja internetowa ładuje oświadczenia tylko raz, więc wszelkie zmiany muszą powodować ponowne załadowanie tych danych statycznych.
W związku z tym menedżerowie mogą wybrać, które oświadczenia należą do poszczególnych ról, a które mają użytkownik po przypisaniu mu roli, a także oświadczenia domyślne. System ma tylko niewielką liczbę użytkowników, więc zarządzanie tymi danymi jest proste
źródło
Aby zrozumieć różnicę między rolami a roszczeniami, musisz zmierzyć się z ograniczeniami ról i poczuć, jak roszczenia pojawiają się w związku z tymi problemami, więc podpaliłem 2 scenariusze, aby rozpoznać moc roszczeń, w których rola nie może rozwiązać tych problemów:
1- Twoja witryna ma dwa moduły (strony, serwis itp.), Pierwszy moduł dla dzieci (poniżej 18 lat) drugi dla dorosłych (powyżej 18 lat) Twoja tożsamość użytkownika ma wniosek o urodziny
musisz stworzyć polisę dla tego roszczenia, aby autoryzacja dla każdego modułu była nadana na tej wartości i jeśli wiek użytkownika przekroczy 18 lat, może on przejść do modułu dla dorosłych, a nie wcześniej
Rola to logiczny typ danych, który możesz mieć lub nie, rola nie ma wartości słodowych
2- Twoja witryna ma rolę użytkownika i nie chcesz uniemożliwić użytkownikom dostępu do pewnych czynności konserwacyjnych bez zmiany kodu
w oświadczeniach można utworzyć zasadę UnderConstrain, która, jeśli prawdziwy użytkownik nie może wyświetlić strony, nada właściwości uprawnienie dla użytkownika roli.
źródło