Uwierzytelnianie i autoryzacja
Uwaga
Ta książka elektroniczna została opublikowana wiosną 2017 r. i od tego czasu nie została zaktualizowana. Jest wiele w książce, która pozostaje cenna, ale niektóre z materiałów są przestarzałe.
Uwierzytelnianie to proces uzyskiwania poświadczeń identyfikacji, takich jak nazwa i hasło od użytkownika, oraz weryfikowanie tych poświadczeń względem urzędu. Jeśli poświadczenia są prawidłowe, jednostka, która przesłała poświadczenia, jest traktowana jako uwierzytelniona tożsamość. Po uwierzytelnieniu tożsamości proces autoryzacji określa, czy ta tożsamość ma dostęp do danego zasobu.
Istnieje wiele metod integrowania uwierzytelniania i autoryzacji w Xamarin.Forms aplikacji komunikującej się z aplikacją internetową MVC ASP.NET, w tym przy użyciu ASP.NET Core Identity, zewnętrznych dostawców uwierzytelniania, takich jak Microsoft, Google, Facebook lub Twitter, oraz oprogramowanie pośredniczące uwierzytelniania. Aplikacja mobilna eShopOnContainers wykonuje uwierzytelnianie i autoryzację za pomocą konteneryzowanej mikrousługi tożsamości korzystającej z serwera IdentityServer 4. Aplikacja mobilna żąda tokenów zabezpieczających z serwera IdentityServer na potrzeby uwierzytelniania użytkownika lub uzyskiwania dostępu do zasobu. Aby maszyna wirtualna IdentityServer wystawiała tokeny w imieniu użytkownika, użytkownik musi zalogować się do serwera IdentityServer. Jednak usługa IdentityServer nie udostępnia interfejsu użytkownika ani bazy danych na potrzeby uwierzytelniania. W związku z tym w aplikacji referencyjnej eShopOnContainers ASP.NET Core Identity jest używana w tym celu.
Uwierzytelnianie
Uwierzytelnianie jest wymagane, gdy aplikacja musi znać tożsamość bieżącego użytkownika. Podstawowym mechanizmem identyfikacji użytkowników ASP.NET Core jest system członkostwa w ASP.NET Core Identity, który przechowuje informacje o użytkowniku w magazynie danych skonfigurowanym przez dewelopera. Zazwyczaj ten magazyn danych będzie magazynem EntityFramework, chociaż magazyny niestandardowe lub pakiety innych firm mogą służyć do przechowywania informacji o tożsamości w usłudze Azure Storage, Usłudze Azure Cosmos DB lub innych lokalizacjach.
W przypadku scenariuszy uwierzytelniania, które korzystają z magazynu danych użytkownika lokalnego i które utrwalają informacje o tożsamości między żądaniami za pośrednictwem plików cookie (co jest typowe w aplikacjach internetowych ASP.NET MVC), ASP.NET Core Identity jest odpowiednim rozwiązaniem. Jednak pliki cookie nie zawsze są naturalnym sposobem utrwalania i przesyłania danych. Na przykład aplikacja internetowa ASP.NET Core, która uwidacznia punkty końcowe RESTful, do których uzyskuje się dostęp z aplikacji mobilnej, zwykle musi używać uwierzytelniania tokenu elementu nośnego, ponieważ pliki cookie nie mogą być używane w tym scenariuszu. Tokeny elementu nośnego można jednak łatwo pobrać i dołączyć do nagłówka autoryzacji żądań internetowych wysyłanych z aplikacji mobilnej.
Wystawianie tokenów elementu nośnego przy użyciu serwera IdentityServer 4
IdentityServer 4 to platforma open source OpenID Connect i OAuth 2.0 dla platformy ASP.NET Core, która może być używana w wielu scenariuszach uwierzytelniania i autoryzacji, w tym wystawiania tokenów zabezpieczających dla lokalnych użytkowników ASP.NET Core Identity.
Uwaga
Funkcje OpenID Connect i OAuth 2.0 są bardzo podobne, ale mają różne obowiązki.
OpenID Connect to warstwa uwierzytelniania oparta na protokole OAuth 2.0. OAuth 2 to protokół, który umożliwia aplikacjom żądanie tokenów dostępu z usługi tokenu zabezpieczającego i używanie ich do komunikowania się z interfejsami API. Delegowanie zmniejsza złożoność zarówno aplikacji klienckich, jak i interfejsów API, ponieważ uwierzytelnianie i autoryzacja mogą być scentralizowane.
Połączenie protokołów OpenID Connect i OAuth 2.0 łączy dwa podstawowe kwestie zabezpieczeń uwierzytelniania i dostępu do interfejsu API, a IdentityServer 4 jest implementacją tych protokołów.
W aplikacjach korzystających z bezpośredniej komunikacji typu klient-mikrousług, takiej jak aplikacja referencyjna eShopOnContainers, dedykowana mikrousługa uwierzytelniania działająca jako usługa tokenu zabezpieczającego (STS) może służyć do uwierzytelniania użytkowników, jak pokazano na rysunku 9-1. Aby uzyskać więcej informacji na temat bezpośredniej komunikacji między klientem a mikrousługą, zobacz Komunikacja między klientem i mikrousługami.
Rysunek 9–1. Uwierzytelnianie za pomocą dedykowanej mikrousługi uwierzytelniania
Aplikacja mobilna eShopOnContainers komunikuje się z mikrousługą tożsamości, która używa serwera IdentityServer 4 do przeprowadzania uwierzytelniania i kontroli dostępu dla interfejsów API. W związku z tym aplikacja mobilna żąda tokenów z serwera IdentityServer na potrzeby uwierzytelniania użytkownika lub uzyskiwania dostępu do zasobu:
- Uwierzytelnianie użytkowników za pomocą usługi IdentityServer jest osiągane przez aplikację mobilną żądającą tokenu tożsamości , który reprezentuje wynik procesu uwierzytelniania. Co najmniej zawiera identyfikator użytkownika oraz informacje o tym, jak i kiedy użytkownik się uwierzytelnił. Może również zawierać dodatkowe dane tożsamości.
- Uzyskiwanie dostępu do zasobu za pomocą usługi IdentityServer jest osiągane przez aplikację mobilną żądającą tokenu dostępu , który umożliwia dostęp do zasobu interfejsu API. Klienci żądają tokenów dostępu i przekazują je do interfejsu API. Tokeny dostępu zawierają informacje o kliencie i użytkowniku (jeśli istnieje). Następnie interfejsy API używają tych informacji do autoryzowania dostępu do danych.
Uwaga
Aby można było żądać tokenów, klient musi być zarejestrowany w usłudze IdentityServer.
Dodawanie serwera IdentityServer do aplikacji internetowej
Aby aplikacja internetowa ASP.NET Core korzystała z serwera IdentityServer 4, należy ją dodać do rozwiązania programu Visual Studio aplikacji internetowej. Aby uzyskać więcej informacji, zobacz Omówienie w dokumentacji IdentityServer.
Po dołączeniu serwera IdentityServer do rozwiązania programu Visual Studio aplikacji internetowej należy ją dodać do potoku przetwarzania żądań HTTP aplikacji internetowej, aby umożliwić obsługę żądań do punktów końcowych OpenID Connect i OAuth 2.0. Jest to osiągane w metodzie Configure
w klasie aplikacji Startup
internetowej, jak pokazano w poniższym przykładzie kodu:
public void Configure(
IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseIdentity();
...
}
Kolejność ma znaczenie w potoku przetwarzania żądań HTTP aplikacji internetowej. W związku z tym należy dodać serwer IdentityServer do potoku przed strukturą interfejsu użytkownika, która implementuje ekran logowania.
Konfigurowanie maszyny wirtualnej IdentityServer
Klasę ConfigureServices
IdentityServer należy skonfigurować w metodzie w klasie aplikacji Startup
internetowej przez wywołanie services.AddIdentityServer
metody, jak pokazano w poniższym przykładzie kodu z aplikacji referencyjnej eShopOnContainers:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentityServer(x => x.IssuerUri = "null")
.AddSigningCredential(Certificate.Get())
.AddAspNetIdentity<ApplicationUser>()
.AddConfigurationStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddOperationalStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.Services.AddTransient<IProfileService, ProfileService>();
}
Po wywołaniu services.AddIdentityServer
metody wywoływane są dodatkowe płynne interfejsy API w celu skonfigurowania następujących elementów:
- Poświadczenia używane do podpisywania.
- Zasoby interfejsu API i tożsamości, do których użytkownicy mogą żądać dostępu.
- Klienci, którzy będą łączyć się z tokenami żądań.
- ASP.NET tożsamość podstawowa.
Napiwek
Dynamiczne ładowanie konfiguracji IdentityServer 4. Interfejsy API serwera IdentityServer 4 umożliwiają konfigurowanie serwera IdentityServer z listy obiektów konfiguracji w pamięci. W aplikacji referencyjnej eShopOnContainers te kolekcje w pamięci są zakodowane w aplikacji. Jednak w scenariuszach produkcyjnych mogą być ładowane dynamicznie z pliku konfiguracji lub z bazy danych.
Aby uzyskać informacje na temat konfigurowania maszyny wirtualnej IdentityServer do używania ASP.NET Core Identity, zobacz Using ASP.NET Core Identity (Używanie tożsamości podstawowej ASP.NET) w dokumentacji IdentityServer.
Konfigurowanie zasobów interfejsu API
Podczas konfigurowania zasobów AddInMemoryApiResources
interfejsu API metoda oczekuje IEnumerable<ApiResource>
kolekcji. Poniższy przykład kodu przedstawia metodę GetApis
, która udostępnia tę kolekcję w aplikacji referencyjnej eShopOnContainers:
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("orders", "Orders Service"),
new ApiResource("basket", "Basket Service")
};
}
Ta metoda określa, że usługa IdentityServer powinna chronić interfejsy API zamówień i koszyka. W związku z tym tokeny dostępu zarządzanego identityServer będą wymagane podczas wykonywania wywołań do tych interfejsów API. Aby uzyskać więcej informacji na temat typu, zobacz Zasób interfejsu ApiResource
API w dokumentacji IdentityServer 4.
Konfigurowanie zasobów tożsamości
Podczas konfigurowania zasobów AddInMemoryIdentityResources
tożsamości metoda oczekuje IEnumerable<IdentityResource>
kolekcji. Zasoby tożsamości to dane, takie jak identyfikator użytkownika, nazwa lub adres e-mail. Każdy zasób tożsamości ma unikatową nazwę i do niego można przypisać dowolne typy oświadczeń, które następnie zostaną uwzględnione w tokenie tożsamości użytkownika. Poniższy przykład kodu przedstawia metodę GetResources
, która udostępnia tę kolekcję w aplikacji referencyjnej eShopOnContainers:
public static IEnumerable<IdentityResource> GetResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
Specyfikacja openID Connect określa niektóre standardowe zasoby tożsamości. Minimalnym wymaganiem jest zapewnienie obsługi emitowania unikatowego identyfikatora dla użytkowników. Jest to osiągane przez uwidacznianie IdentityResources.OpenId
zasobu tożsamości.
Uwaga
Klasa IdentityResources
obsługuje wszystkie zakresy zdefiniowane w specyfikacji OpenID Connect (openid, email, profil, telefon i adres).
Usługa IdentityServer obsługuje również definiowanie niestandardowych zasobów tożsamości. Aby uzyskać więcej informacji na temat IdentityResource
typu, zobacz Identity Resource (Zasób tożsamości) w dokumentacji IdentityServer 4.
Konfigurowanie klientów
Klienci to aplikacje, które mogą żądać tokenów z maszyny wirtualnej IdentityServer. Zazwyczaj dla każdego klienta należy zdefiniować następujące ustawienia co najmniej:
- Unikatowy identyfikator klienta.
- Dozwolone interakcje z usługą tokenu (nazywane typem przyznawania).
- Lokalizacja, w której są wysyłane tożsamości i tokeny dostępu (nazywane identyfikatorem URI przekierowania).
- Lista zasobów, do których klient ma dostęp (znany jako zakresy).
Podczas konfigurowania klientów AddInMemoryClients
metoda oczekuje IEnumerable<Client>
kolekcji. Poniższy przykład kodu przedstawia konfigurację aplikacji mobilnej eShopOnContainers w GetClients
metodzie, która udostępnia tę kolekcję w aplikacji referencyjnej eShopOnContainers:
public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl)
{
return new List<Client>
{
...
new Client
{
ClientId = "xamarin",
ClientName = "eShop Xamarin OpenId Client",
AllowedGrantTypes = GrantTypes.Hybrid,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { clientsUrl["Xamarin"] },
RequireConsent = false,
RequirePkce = true,
PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" },
AllowedCorsOrigins = { "http://eshopxamarin" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"orders",
"basket"
},
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true
},
...
};
}
Ta konfiguracja określa dane dla następujących właściwości:
ClientId
: unikatowy identyfikator klienta.ClientName
: nazwa wyświetlana klienta, która jest używana do rejestrowania i ekranu zgody.AllowedGrantTypes
: określa, w jaki sposób klient chce wchodzić w interakcję z maszyną wirtualną IdentityServer. Aby uzyskać więcej informacji, zobacz Konfigurowanie przepływu uwierzytelniania.ClientSecrets
: określa poświadczenia wpisu tajnego klienta, które są używane podczas żądania tokenów z punktu końcowego tokenu.RedirectUris
: określa dozwolone identyfikatory URI, do których mają być zwracane tokeny lub kody autoryzacji.RequireConsent
: określa, czy jest wymagany ekran zgody.RequirePkce
: określa, czy klienci korzystający z kodu autoryzacji muszą wysłać klucz dowodowy.PostLogoutRedirectUris
: określa dozwolone identyfikatory URI do przekierowania do po wylogowaniu.AllowedCorsOrigins
: określa źródło klienta, aby serwer IdentityServer mógł zezwalać na wywołania między źródłami z źródła.AllowedScopes
: określa zasoby, do których klient ma dostęp. Domyślnie klient nie ma dostępu do żadnych zasobów.AllowOfflineAccess
: określa, czy klient może żądać tokenów odświeżania.
Konfigurowanie przepływu uwierzytelniania
Przepływ uwierzytelniania między klientem a serwerem IdentityServer można skonfigurować, określając typy dotacji we Client.AllowedGrantTypes
właściwości . Specyfikacje protokołu OpenID Connect i OAuth 2.0 definiują szereg przepływów uwierzytelniania, w tym:
- Niejawny. Ten przepływ jest zoptymalizowany pod kątem aplikacji opartych na przeglądarce i powinien być używany tylko do uwierzytelniania użytkowników lub żądań tokenów uwierzytelniania i dostępu. Wszystkie tokeny są przesyłane za pośrednictwem przeglądarki, dlatego zaawansowane funkcje, takie jak tokeny odświeżania, nie są dozwolone.
- Kod autoryzacji. Ten przepływ umożliwia pobieranie tokenów w kanale zaplecza, a nie kanału frontonu przeglądarki, a także obsługę uwierzytelniania klienta.
- Hybrydowy. Ten przepływ jest kombinacją typów przyznawania kodu niejawnego i autoryzacji. Token tożsamości jest przesyłany za pośrednictwem kanału przeglądarki i zawiera podpisaną odpowiedź protokołu wraz z innymi artefaktami, takimi jak kod autoryzacji. Po pomyślnej weryfikacji odpowiedzi kanał zaplecza powinien służyć do pobierania tokenu dostępu i odświeżania.
Napiwek
Użyj przepływu uwierzytelniania hybrydowego. Przepływ uwierzytelniania hybrydowego ogranicza liczbę ataków mających zastosowanie do kanału przeglądarki i jest zalecanym przepływem dla aplikacji natywnych, które chcą pobierać tokeny dostępu (i ewentualnie odświeżać tokeny).
Aby uzyskać więcej informacji na temat przepływów uwierzytelniania, zobacz Grant Types (Udzielanie typów ) w dokumentacji identityServer 4.
Wykonywanie uwierzytelniania
Aby maszyna wirtualna IdentityServer wystawiała tokeny w imieniu użytkownika, użytkownik musi zalogować się do serwera IdentityServer. Jednak usługa IdentityServer nie udostępnia interfejsu użytkownika ani bazy danych na potrzeby uwierzytelniania. W związku z tym w aplikacji referencyjnej eShopOnContainers ASP.NET Core Identity jest używana w tym celu.
Aplikacja mobilna eShopOnContainers uwierzytelnia się za pomocą klasy IdentityServer przy użyciu przepływu uwierzytelniania hybrydowego, który przedstawiono na rysunku 9-2.
Rysunek 9–2. Ogólne omówienie procesu logowania
Żądanie logowania jest wykonywane na adres <base endpoint>:5105/connect/authorize
. Po pomyślnym uwierzytelnieniu usługa IdentityServer zwraca odpowiedź uwierzytelniania zawierającą kod autoryzacji i token tożsamości. Kod autoryzacji jest następnie wysyłany do <base endpoint>:5105/connect/token
programu , który odpowiada za pomocą tokenów dostępu, tożsamości i odświeżania.
Aplikacja mobilna eShopOnContainers wylogowała się z serwera IdentityServer, wysyłając żądanie do <base endpoint>:5105/connect/endsession
obiektu z dodatkowymi parametrami. Po wylogowaniu usługa IdentityServer odpowiada, wysyłając identyfikator URI przekierowania po wylogowaniu z powrotem do aplikacji mobilnej. Rysunek 9–3 ilustruje ten proces.
Rysunek 9–3. Ogólne omówienie procesu wylogowywanie
W aplikacji mobilnej eShopOnContainers komunikacja z maszyną wirtualną IdentityServer jest wykonywana przez klasę IdentityService
, która implementuje IIdentityService
interfejs. Ten interfejs określa, że klasa implementowania musi dostarczać CreateAuthorizationRequest
metody , CreateLogoutRequest
i GetTokenAsync
.
Logowanie
Gdy użytkownik naciągnie przycisk LOGIN w LoginView
klasie , SignInCommand
zostanie wykonany element w LoginViewModel
klasie, który z kolei wykonuje metodę SignInAsync
. Poniższy przykład kodu przedstawia tę metodę:
private async Task SignInAsync()
{
...
LoginUrl = _identityService.CreateAuthorizationRequest();
IsLogin = true;
...
}
Ta metoda wywołuje metodę CreateAuthorizationRequest
w IdentityService
klasie, która jest pokazana w poniższym przykładzie kodu:
public string CreateAuthorizationRequest()
{
// Create URI to authorization endpoint
var authorizeRequest = new AuthorizeRequest(GlobalSetting.Instance.IdentityEndpoint);
// Dictionary with values for the authorize request
var dic = new Dictionary<string, string>();
dic.Add("client_id", GlobalSetting.Instance.ClientId);
dic.Add("client_secret", GlobalSetting.Instance.ClientSecret);
dic.Add("response_type", "code id_token");
dic.Add("scope", "openid profile basket orders locations marketing offline_access");
dic.Add("redirect_uri", GlobalSetting.Instance.Callback);
dic.Add("nonce", Guid.NewGuid().ToString("N"));
dic.Add("code_challenge", CreateCodeChallenge());
dic.Add("code_challenge_method", "S256");
// Add CSRF token to protect against cross-site request forgery attacks.
var currentCSRFToken = Guid.NewGuid().ToString("N");
dic.Add("state", currentCSRFToken);
var authorizeUri = authorizeRequest.Create(dic);
return authorizeUri;
}
Ta metoda tworzy identyfikator URI dla punktu końcowego autoryzacji serwera IdentityServer z wymaganymi parametrami. Punkt końcowy autoryzacji znajduje się na /connect/authorize
porcie 5105 podstawowego punktu końcowego uwidocznionego jako ustawienie użytkownika. Aby uzyskać więcej informacji na temat ustawień użytkownika, zobacz Zarządzanie konfiguracją.
Uwaga
Powierzchnia ataków aplikacji mobilnej eShopOnContainers jest ograniczona przez zaimplementowanie rozszerzenia Proof Key for Code Exchange (PKCE) do protokołu OAuth. PKCE chroni kod autoryzacji przed użyciem, jeśli zostanie przechwycony. Jest to osiągane przez klienta generującego weryfikator wpisów tajnych, skrót, który jest przekazywany w żądaniu autoryzacji i który jest prezentowany bez skrótu podczas realizacji kodu autoryzacji. Aby uzyskać więcej informacji na temat PKCE, zobacz Proof Key for Code Exchange by OAuth Public Clients (Klucz weryfikacji wymiany kodu przez klientów publicznych OAuth) w witrynie internetowej Grupy zadaniowej w Internecie.
Zwrócony identyfikator URI jest przechowywany we LoginUrl
właściwości LoginViewModel
klasy. Gdy IsLogin
właściwość stanie się true
wartością , WebView
właściwość w LoginView
obiekcie stanie się widoczna. Dane WebView
wiążą jego Source
właściwość z właściwością LoginUrl
LoginViewModel
klasy, dlatego wysyła żądanie logowania do klasy IdentityServer, gdy LoginUrl
właściwość jest ustawiona na punkt końcowy autoryzacji IdentityServer. Gdy usługa IdentityServer odbierze to żądanie i użytkownik nie zostanie uwierzytelniony, WebView
nastąpi przekierowanie do skonfigurowanej strony logowania, która jest wyświetlana na rysunku 9–4.
Rysunek 9–4. Strona logowania wyświetlana przez element WebView
Po zakończeniu WebView
logowania nastąpi przekierowanie do zwracanego identyfikatora URI. Ta WebView
nawigacja spowoduje NavigateAsync
wykonanie metody w LoginViewModel
klasie, która jest wyświetlana w poniższym przykładzie kodu:
private async Task NavigateAsync(string url)
{
...
var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.Code))
{
var userToken = await _identityService.GetTokenAsync(authResponse.Code);
string accessToken = userToken.AccessToken;
if (!string.IsNullOrWhiteSpace(accessToken))
{
Settings.AuthAccessToken = accessToken;
Settings.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();
}
}
...
}
Ta metoda analizuje odpowiedź uwierzytelniania zawartą w zwracanym identyfikatorze URI i pod warunkiem, że istnieje prawidłowy kod autoryzacji, wysyła żądanie do punktu końcowego tokenu IdentityServer, przekazując kod autoryzacji, weryfikator wpisów tajnych PKCE i inne wymagane parametry. Punkt końcowy tokenu znajduje się na /connect/token
porcie 5105 podstawowego punktu końcowego uwidocznionego jako ustawienie użytkownika. Aby uzyskać więcej informacji na temat ustawień użytkownika, zobacz Zarządzanie konfiguracją.
Napiwek
Zweryfikuj zwracane identyfikatory URI. Mimo że aplikacja mobilna eShopOnContainers nie weryfikuje zwracanego identyfikatora URI, najlepszym rozwiązaniem jest sprawdzenie, czy zwracany identyfikator URI odwołuje się do znanej lokalizacji, aby zapobiec atakom typu open-redirect.
Jeśli punkt końcowy tokenu otrzyma prawidłowy kod autoryzacji i weryfikator wpisów tajnych PKCE, odpowiada za pomocą tokenu dostępu, tokenu tożsamości i tokenu odświeżania. Token dostępu (który umożliwia dostęp do zasobów interfejsu API) i token tożsamości są następnie przechowywane jako ustawienia aplikacji, a nawigacja po stronie jest wykonywana. W związku z tym ogólny efekt w aplikacji mobilnej eShopOnContainers jest następujący: pod warunkiem, że użytkownicy będą mogli pomyślnie uwierzytelnić się za pomocą identityServer, są one nawigowane do MainView
strony, która jest TabbedPage
wyświetlana CatalogView
jako wybrana karta.
Aby uzyskać informacje na temat nawigacji między stronami, zobacz Nawigacja. Aby uzyskać informacje na temat sposobu, w jaki WebView
nawigacja powoduje wykonanie metody modelu widoku, zobacz Wywoływanie nawigacji przy użyciu zachowań. Aby uzyskać informacje o ustawieniach aplikacji, zobacz Zarządzanie konfiguracją.
Uwaga
Aplikacja eShopOnContainers umożliwia również pozorne logowanie, gdy aplikacja jest skonfigurowana do korzystania z pozornych usług w programie SettingsView
. W tym trybie aplikacja nie komunikuje się z usługą IdentityServer, zamiast tego zezwala użytkownikowi na logowanie się przy użyciu poświadczeń.
Wylogowywanie
Gdy użytkownik naciągnie przycisk Wyloguj się w ProfileView
klasie , LogoutCommand
zostanie wykonany element w ProfileViewModel
klasie, który z kolei wykonuje metodę LogoutAsync
. Ta metoda wykonuje nawigację po LoginView
stronie, przekazując LogoutParameter
wystąpienie ustawione jako true
parametr. Aby uzyskać więcej informacji na temat przekazywania parametrów podczas nawigacji na stronie, zobacz Przekazywanie parametrów podczas nawigacji.
Po utworzeniu widoku i przejściu do InitializeAsync
niej jest wykonywana metoda skojarzonego modelu widoku, która następnie wykonuje Logout
metodę LoginViewModel
klasy, która jest wyświetlana w poniższym przykładzie kodu:
private void Logout()
{
var authIdToken = Settings.AuthIdToken;
var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);
if (!string.IsNullOrEmpty(logoutRequest))
{
// Logout
LoginUrl = logoutRequest;
}
...
}
Ta metoda wywołuje metodę CreateLogoutRequest
w IdentityService
klasie, przekazując token tożsamości pobrany z ustawień aplikacji jako parametr. Aby uzyskać więcej informacji na temat ustawień aplikacji, zobacz Zarządzanie konfiguracją. Poniższy przykład kodu przedstawia metodę CreateLogoutRequest
:
public string CreateLogoutRequest(string token)
{
...
return string.Format("{0}?id_token_hint={1}&post_logout_redirect_uri={2}",
GlobalSetting.Instance.LogoutEndpoint,
token,
GlobalSetting.Instance.LogoutCallback);
}
Ta metoda tworzy identyfikator URI do końcowego punktu końcowego sesji serwera IdentityServer z wymaganymi parametrami. Punkt końcowy sesji znajduje się na /connect/endsession
porcie 5105 podstawowego punktu końcowego uwidocznionego jako ustawienie użytkownika. Aby uzyskać więcej informacji na temat ustawień użytkownika, zobacz Zarządzanie konfiguracją.
Zwrócony identyfikator URI jest przechowywany we LoginUrl
właściwości LoginViewModel
klasy. IsLogin
Gdy właściwość ma true
wartość , WebView
właściwość w obiekcie jest widocznaLoginView
. Dane WebView
wiążą jego Source
właściwość z LoginUrl
właściwością LoginViewModel
klasy, dlatego wysyła żądanie wylogowania do klasy IdentityServer, gdy LoginUrl
właściwość jest ustawiona na punkt końcowy sesji identityServer. Gdy usługa IdentityServer odbierze to żądanie, pod warunkiem, że użytkownik jest zalogowany, wyloguj się. Uwierzytelnianie jest śledzone za pomocą pliku cookie zarządzanego przez oprogramowanie pośredniczące uwierzytelniania plików cookie z ASP.NET Core. W związku z tym wylogowanie się z serwera IdentityServer usuwa plik cookie uwierzytelniania i wysyła identyfikator URI przekierowania po wylogowaniu z powrotem do klienta.
W aplikacji WebView
mobilnej element zostanie przekierowany do identyfikatora URI przekierowania po wylogowaniu. Ta WebView
nawigacja spowoduje NavigateAsync
wykonanie metody w LoginViewModel
klasie, która jest wyświetlana w poniższym przykładzie kodu:
private async Task NavigateAsync(string url)
{
...
Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty;
IsLogin = false;
LoginUrl = _identityService.CreateAuthorizationRequest();
...
}
Ta metoda czyści zarówno token tożsamości, jak i token dostępu z ustawień aplikacji, i ustawia IsLogin
właściwość na false
wartość , co powoduje WebView
, że na LoginView
stronie stanie się niewidoczny. LoginUrl
Na koniec właściwość jest ustawiona na identyfikator URI punktu końcowego autoryzacji identityServer z wymaganymi parametrami w ramach przygotowań do następnego zainicjowania logowania przez użytkownika.
Aby uzyskać informacje na temat nawigacji między stronami, zobacz Nawigacja. Aby uzyskać informacje na temat sposobu, w jaki WebView
nawigacja powoduje wykonanie metody modelu widoku, zobacz Wywoływanie nawigacji przy użyciu zachowań. Aby uzyskać informacje o ustawieniach aplikacji, zobacz Zarządzanie konfiguracją.
Uwaga
EShopOnContainers umożliwia również pozorne wylogowywanie, gdy aplikacja jest skonfigurowana do korzystania z pozornych usług w widoku SettingsView. W tym trybie aplikacja nie komunikuje się z usługą IdentityServer i zamiast tego czyści wszystkie przechowywane tokeny z ustawień aplikacji.
Autoryzacja
Po uwierzytelnieniu ASP.NET Core internetowych interfejsów API często muszą autoryzować dostęp, co umożliwia usłudze udostępnianie interfejsów API niektórym uwierzytelnionymi użytkownikom, ale nie wszystkim.
Ograniczenie dostępu do trasy ASP.NET Core MVC można osiągnąć, stosując atrybut Authorize do kontrolera lub akcji, co ogranicza dostęp do kontrolera lub akcji dla uwierzytelnionych użytkowników, jak pokazano w poniższym przykładzie kodu:
[Authorize]
public class BasketController : Controller
{
...
}
Jeśli nieautoryzowany użytkownik próbuje uzyskać dostęp do kontrolera lub akcji oznaczonej atrybutem Authorize
, struktura MVC zwraca kod stanu HTTP 401 (nieautoryzowany).
Uwaga
Parametry można określić na atrybucie, Authorize
aby ograniczyć interfejs API do określonych użytkowników. Aby uzyskać więcej informacji, zobacz Autoryzacja.
Serwer IdentityServer można zintegrować z przepływem pracy autoryzacji, aby tokeny dostępu zapewniały autoryzację kontroli. To podejście przedstawiono na rysunku 9–5.
Rysunek 9–5. Autoryzacja według tokenu dostępu
Aplikacja mobilna eShopOnContainers komunikuje się z mikrousługą tożsamości i żąda tokenu dostępu w ramach procesu uwierzytelniania. Token dostępu jest następnie przekazywany do interfejsów API udostępnianych przez mikrousługi zamawiania i koszyka w ramach żądań dostępu. Tokeny dostępu zawierają informacje o kliencie i użytkowniku. Następnie interfejsy API używają tych informacji do autoryzowania dostępu do danych. Aby uzyskać informacje o sposobie konfigurowania serwera IdentityServer w celu ochrony interfejsów API, zobacz Konfigurowanie zasobów interfejsu API.
Konfigurowanie maszyny wirtualnej IdentityServer do wykonania autoryzacji
Aby wykonać autoryzację za pomocą serwera IdentityServer, jego oprogramowanie pośredniczące autoryzacji musi zostać dodane do potoku żądania HTTP aplikacji internetowej. Oprogramowanie pośredniczące jest dodawane w metodzie ConfigureAuth
w klasie aplikacji Startup
internetowej, która jest wywoływana z Configure
metody i jest pokazana w poniższym przykładzie kodu z aplikacji referencyjnej eShopOnContainers:
protected virtual void ConfigureAuth(IApplicationBuilder app)
{
var identityUrl = Configuration.GetValue<string>("IdentityUrl");
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = identityUrl.ToString(),
ScopeName = "basket",
RequireHttpsMetadata = false
});
}
Ta metoda zapewnia dostęp do interfejsu API tylko przy użyciu prawidłowego tokenu dostępu. Oprogramowanie pośredniczące weryfikuje token przychodzący, aby upewnić się, że jest wysyłany z zaufanego wystawcy i sprawdza, czy token jest prawidłowy do użycia z interfejsem API, który go odbiera. W związku z tym przejście do kontrolera zamówienia lub koszyka zwróci kod stanu HTTP 401 (nieautoryzowany) wskazujący, że token dostępu jest wymagany.
Uwaga
Oprogramowanie pośredniczące autoryzacji serwera IdentityServer musi zostać dodane do potoku żądania HTTP aplikacji internetowej przed dodaniem wzorca MVC za pomocą app.UseMvc()
polecenia lub app.UseMvcWithDefaultRoute()
.
Wykonywanie żądań dostępu do interfejsów API
Podczas wprowadzania żądań do mikrousług zamówień i koszyka token dostępu uzyskany z serwera IdentityServer podczas procesu uwierzytelniania musi zostać uwzględniony w żądaniu, jak pokazano w poniższym przykładzie kodu:
var authToken = Settings.AuthAccessToken;
Order = await _ordersService.GetOrderAsync(Convert.ToInt32(order.OrderNumber), authToken);
Token dostępu jest przechowywany jako ustawienie aplikacji i jest pobierany z magazynu specyficznego dla platformy i dołączony do wywołania GetOrderAsync
metody w OrderService
klasie .
Podobnie token dostępu musi zostać uwzględniony podczas wysyłania danych do chronionego interfejsu API IdentityServer, jak pokazano w poniższym przykładzie kodu:
var authToken = Settings.AuthAccessToken;
await _basketService.UpdateBasketAsync(new CustomerBasket
{
BuyerId = userInfo.UserId,
Items = BasketItems.ToList()
}, authToken);
Token dostępu jest pobierany z magazynu specyficznego dla platformy i uwzględniany w wywołaniu UpdateBasketAsync
metody w BasketService
klasie .
Klasa RequestProvider
w aplikacji mobilnej eShopOnContainers używa HttpClient
klasy do przesyłania żądań do interfejsów API RESTful uwidocznionych przez aplikację referencyjną eShopOnContainers. Podczas wprowadzania żądań do interfejsów API zamawiania i koszyka, które wymagają autoryzacji, należy dołączyć prawidłowy token dostępu do żądania. Jest to osiągane przez dodanie tokenu dostępu do nagłówków HttpClient
wystąpienia, jak pokazano w poniższym przykładzie kodu:
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
Właściwość DefaultRequestHeaders
HttpClient
klasy uwidacznia nagłówki wysyłane za pomocą każdego żądania, a token dostępu jest dodawany do Authorization
nagłówka poprzedzonego ciągiem Bearer
. Gdy żądanie jest wysyłane do interfejsu API RESTful, wartość Authorization
nagłówka jest wyodrębniona i weryfikowana, aby upewnić się, że jest wysyłany z zaufanego wystawcy i służy do określania, czy użytkownik ma uprawnienia do wywoływania interfejsu API, który go odbiera.
Aby uzyskać więcej informacji na temat sposobu, w jaki aplikacja mobilna eShopOnContainers wysyła żądania internetowe, zobacz Uzyskiwanie dostępu do danych zdalnych.
Podsumowanie
Istnieje wiele metod integrowania uwierzytelniania i autoryzacji w aplikacji komunikującej się z aplikacją Xamarin.Forms internetową MVC ASP.NET. Aplikacja mobilna eShopOnContainers wykonuje uwierzytelnianie i autoryzację za pomocą konteneryzowanej mikrousługi tożsamości korzystającej z serwera IdentityServer 4. IdentityServer to platforma open source OpenID Connect i OAuth 2.0 dla platformy ASP.NET Core, która integruje się z ASP.NET Core Identity w celu przeprowadzania uwierzytelniania tokenu elementu nośnego.
Aplikacja mobilna żąda tokenów zabezpieczających z serwera IdentityServer na potrzeby uwierzytelniania użytkownika lub uzyskiwania dostępu do zasobu. Podczas uzyskiwania dostępu do zasobu token dostępu musi być uwzględniony w żądaniu do interfejsów API, które wymagają autoryzacji. Oprogramowanie pośredniczące IdentityServer weryfikuje przychodzące tokeny dostępu, aby upewnić się, że są wysyłane z zaufanego wystawcy i że są one prawidłowe do użycia z interfejsem API, który je odbiera.