Najlepsze rozwiązania dotyczące ról i oświadczeń w ASP.NET Identity


98

Jestem zupełnie nowy w używaniu programu claimsin ASP.NETIdentityi 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ę Claimsjako podkategorie do tych, Rolesktó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();
}

1
Tak więc mam teraz ten sam problem, jak go rozwiązujesz i jak możesz przypisać uprawnienia w aplikacji?
Loai

Odpowiedzi:


78

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 :

Po utworzeniu tożsamości można do niej przypisać jedno lub więcej oświadczeń wystawionych przez zaufaną stronę. Oświadczenie to para nazwa-wartość, która reprezentuje to, czym jest podmiot, a nie to, co podmiot może zrobić.

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.


7
Nie sądzę, aby to było całkowicie dokładne. Uważam, że oświadczenia wskazują tożsamość, a nie autoryzację. To, do czego są upoważnieni, zarządza się oddzielnie. Oznacza to, że mogą mieć roszczenie, w którym data urodzenia wskazuje, że ukończyli 18 lat. Roszczenie to zostanie przekazane menedżerowi autoryzacji, który może zawierać regułę mówiącą, że „jeśli mają ukończone 18 lat, mogą edytować zasób X”, ale samo roszczenie nie wskazuje, co mogą / nie mogą zrobić lub uzyskać do nich dostęp. To samo dotyczy ról i innych roszczeń. Oświadczenia wskazują, kim jesteś, i służą do określania, co możesz zrobić, ale nie mówią bezpośrednio
ChrisC

Dokumentacja pomocnicza dla @ChrisC pochodzi z autoryzacji opartej na oświadczeniach firmy Microsoft w ASP.NET Core : „Oświadczenie to para wartości nazwy, która reprezentuje podmiot, a nie to, co podmiot może zrobić”.
DrGriff

@DrGriff Dziękujemy za udostępnienie tego linku; Przez jakiś czas pytałem o dokładność podanego opisu; Myślę, że teraz wyjaśniłem odpowiedź na podstawie tego linku.
Claies

31

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


8

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


4

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.