29

Wdrażam usługę WWW RESTful przy użyciu interfejsu API ASP.Net. Do wykonania części uwierzytelniającej doszedłem do korzystania z uwierzytelniania podstawowego + SSL. Jaki jest najlepszy/prawidłowy sposób realizacji tego?ASP.net Web API Usługa sieciowa RESTful + uwierzytelnianie podstawowe

Pierwszą próbą było zrobienie tego ręcznie, parsowanie nagłówka Authorization, dekodowanie i weryfikacja użytkownika względem mojej bazy danych. Działa, ale zastanawiam się, czy czegoś brakuje.

Widziałem kilka rozwiązań wykorzystujących role użytkowników i zleceniodawców. Chociaż nie jestem pewien, co tak naprawdę robią, jestem prawie pewien, że nie będę ich potrzebował, ponieważ w mojej bazie danych definiuję moich własnych użytkowników i ich role.

Ponadto, czego jeszcze nie do końca rozumiem, jest to, że konsumenci usługi muszą wysłać poświadczenia przy każdym żądaniu lub są w jakiś sposób buforowane. Czy moja usługa powinna coś zrobić, aby tak się stało, lub czy to całkowicie zależy od konsumenta, aby sobie z tym poradzić?

I ostatnie pytanie dotyczące klientów wysyłających żądania za pomocą javascript. Czy wystąpią jakiekolwiek problemy z "żądaniem krzyżowym", jeśli spróbują skorzystać z usługi?

Odpowiedz

25

Jamie Kurtze zapewnia dobre wyjaśnienie stosowania tutaj Basic Authentication ASP.NET Web API REST Security Basics

Z mojego rozumienia, jeśli chcesz, aby twoje żądania były bezpaństwowcami, każde żądanie będzie wymagać e pole Uwierzytelnianie, które ma być ustawione:

Jamie Kurtze zawija niezbędny kod w klasie pochodnej DelegateHandler, a Rick Strahl sprawdza, czy wywołanie jest prawidłowe przy użyciu filtru. Więcej informacji można znaleźć na jego blogu na ten temat pod adresem A WebAPI Basic Authentication Authorization Filter

+0

Witam, kiedy napisałem to pytanie, nie było dla mnie jasne, w jaki sposób używane są Principals and Roles (i jak są one powiązane z moimi własnymi użytkownikami). Teraz robię to, używając nagłówka Uwierzytelnianie do przekazywania poświadczeń i modułu Http w celu jednorodnego sprawdzenia ich. Będę chociaż przeglądał twoje linki, gdy będę miał trochę czasu. – alfoks

+0

Moja implementacja działa dobrze, ale są to dobre linki dla przyszłych czytelników. – alfoks

+1

Twoje pierwsze połączenie z ASP.NET Web Api REST Security Basics jest martwe –

1
+0

Te linki nie odpowiadają na moje pytania. Możliwe tylko pierwsze pytanie, ale odnoszą się one do konfiguracji biblioteki bezpieczeństwa innej firmy. Z powodu braku czasu chcę uniknąć używania kolejnych bibliotek. – alfoks

21

Użyć podstawowego uwierzytelnienia dla żądania początkowego (logowania), dodając atrybut [BasicHttpAuthorize] do odpowiednich kontrolerów/metod. W razie potrzeby podaj atrybuty Users i Roles. Definiowanie BasicHttpAuthorizeAttribute jako wyspecjalizowany AuthorizeAttribute tak:

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool IsAuthorized(HttpActionContext actionContext) 
    { 
     if (Thread.CurrentPrincipal.Identity.Name.Length == 0) { // If an identity has not already been established by other means: 
      AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization; 
      if (string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0) { 
       string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter)); 
       int separatorIndex = credentials.IndexOf(':'); 
       if (separatorIndex >= 0) { 
        string userName = credentials.Substring(0, separatorIndex); 
        string password = credentials.Substring(separatorIndex + 1); 
        if (Membership.ValidateUser(userName, password)) 
         Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), System.Web.Security.Roles.Provider.GetRolesForUser(userName)); 
       } 
      } 
     } 
     return base.IsAuthorized(actionContext); 
    } 
} 

mieć początkową reakcję zawierać klucz API dla użytkownika. Użyj klucza API dla kolejnych połączeń. W ten sposób uwierzytelnianie klienta pozostaje ważne, nawet jeśli użytkownik zmieni nazwę użytkownika lub hasło. Jednak zmieniając hasło, daj użytkownikowi opcję "odłączania klientów", którą implementujesz, usuwając klucz API na serwerze.

+0

Rozwiązałem już problem, ale dziękuję za odpowiedź. Łatwiej jest mi przekazywać we wszystkich wywołaniach API nazwę użytkownika i hasło w nagłówku Authorization, zamiast sugerować podejście tokena. – alfoks

+0

@Edward Wielkie dzięki za twój post, uważam, że najbardziej pomaga w pełni. Jakiego mechanizmu użytkownika i roli używasz w tym przykładzie? BEcause Widzę, że tworzysz nowy GenericPrinsiple. Czy mógłbyś wyjaśnić, w jaki sposób mogę zintegrować Twoje rozwiązanie z nowym, pustym projektem aplikacji sieci Web. – Zapnologica

+0

@Zapnologica Ten kod używa starego modelu tożsamości członkostwa, którego Microsoft używał przed VS2013. Szablony z VS2013 używają nowego systemu identyfikacji opartego na OWIN, który wykonuje niestandardową nazwę użytkownika/hasło, a następnie wykorzystuje tokeny na okaziciela, eliminując potrzebę BasicHttpAuthorize. –