Аутентификация и авторизацияAuthentication and Authorization

Проверка подлинности — это процесс получения учетных данных идентификации, такие как имя и пароль пользователя и проверки этих учетных данных на наличие полномочий.Authentication is the process of obtaining identification credentials such as name and password from a user, and validating those credentials against an authority. Если учетные данные действительны, сущность, которая отправлена учетные данные, считается прошедшим проверку подлинности.If the credentials are valid, the entity that submitted the credentials is considered an authenticated identity. После проверки подлинности удостоверения процесс авторизации определяет, имеет ли это удостоверение доступ к конкретному ресурсу.Once an identity has been authenticated, an authorization process determines whether that identity has access to a given resource.

Существует много подходов к интеграции проверки подлинности и авторизации в приложение Xamarin.Forms, которое взаимодействует с веб-приложения ASP.NET MVC, включая поставщиков внешней проверки подлинности, например Microsoft, Google, с помощью ASP.NET Core Identity Facebook или Twitter и проверки подлинности по промежуточного слоя.There are many approaches to integrating authentication and authorization into a Xamarin.Forms app that communicates with an ASP.NET MVC web application, including using ASP.NET Core Identity, external authentication providers such as Microsoft, Google, Facebook, or Twitter, and authentication middleware. В мобильном приложении eShopOnContainers выполняет проверку подлинности и авторизации с помощью микрослужбы контейнерных удостоверений, которая использует IdentityServer 4.The eShopOnContainers mobile app performs authentication and authorization with a containerized identity microservice that uses IdentityServer 4. Мобильное приложение запрашивает у IdentityServer, маркеры безопасности, для проверки подлинности пользователя или для доступа к ресурсу.The mobile app requests security tokens from IdentityServer, either for authenticating a user or for accessing a resource. Для IdentityServer для выдачи маркеров от имени пользователя пользователь должен войти в к IdentityServer.For IdentityServer to issue tokens on behalf of a user, the user must sign-in to IdentityServer. Тем не менее сервер не предоставляет пользовательский интерфейс или базы данных для проверки подлинности.However, IdentityServer doesn't provide a user interface or database for authentication. Таким образом в образце приложения eShopOnContainers, для этой цели используется удостоверение ASP.NET Core.Therefore, in the eShopOnContainers reference application, ASP.NET Core Identity is used for this purpose.

Проверка подлинностиAuthentication

Проверка подлинности необходима, если приложению должно быть известно удостоверение текущего пользователя.Authentication is required when an application needs to know the identity of the current user. ASP.NET Core основным механизмом для идентификации пользователей является система членства ASP.NET Core Identity, которая хранит сведения о пользователе в хранилище данных, настроенном разработчиком.ASP.NET Core's primary mechanism for identifying users is the ASP.NET Core Identity membership system, which stores user information in a data store configured by the developer. Как правило это хранилище данных будет хранилище EntityFramework, хотя пользовательские хранилища или пакеты сторонних может использоваться для хранения данных удостоверений в хранилище Azure, Azure Cosmos DB или других местах.Typically, this data store will be an EntityFramework store, though custom stores or third party packages can be used to store identity information in Azure storage, Azure Cosmos DB, or other locations.

Сценарии проверки подлинности, которые делают использование хранилища данных локального пользователя, и которые сохраняются сведения об удостоверениях между запросами с помощью файлов cookie (как обычно бывает в веб-приложений ASP.NET MVC), удостоверение ASP.NET Core — это подходящее решение.For authentication scenarios that make use of a local user data store, and that persist identity information between requests via cookies (as is typical in ASP.NET MVC web applications), ASP.NET Core Identity is a suitable solution. Тем не менее файлы cookie не всегда нецелесообразно хранить и передавать данные.However, cookies are not always a natural means of persisting and transmitting data. Например веб-приложение ASP.NET Core, которая предоставляет RESTful конечных точек, доступных из мобильного приложения обычно требуется для использования проверки подлинности токена носителя, так как файлы cookie не может использоваться в этом сценарии.For example, an ASP.NET Core web application that exposes RESTful endpoints that are accessed from a mobile app will typically need to use bearer token authentication, since cookies can't be used in this scenario. Тем не менее токены носителя можно легко получать и содержится в заголовке авторизации веб-запросов, сделанных в мобильном приложении.However, bearer tokens can easily be retrieved and included in the authorization header of web requests made from the mobile app.

Выдает маркеры носителя, с помощью IdentityServer 4Issuing Bearer Tokens using IdentityServer 4

IdentityServer 4 — фреймворк с открытым кодом OpenID Connect и OAuth 2.0 для ASP.NET Core, который может использоваться для многих сценариев проверки подлинности и авторизации, включая выдает маркеры безопасности для локальных пользователей удостоверения ASP.NET Core.IdentityServer 4 is an open source OpenID Connect and OAuth 2.0 framework for ASP.NET Core, which can be used for many authentication and authorization scenarios including issuing security tokens for local ASP.NET Core Identity users.

Примечание

OpenID Connect и OAuth 2.0 очень похожи, имея различные обязанности.OpenID Connect and OAuth 2.0 are very similar, while having different responsibilities.

OpenID Connect представляет собой уровень проверки подлинности на основе протокола OAuth 2.0.OpenID Connect is an authentication layer on top of the OAuth 2.0 protocol. OAuth 2 — это протокол, который позволяет приложениям запрашивать маркеры доступа от службы маркеров безопасности и использовать их для взаимодействия с интерфейсами API.OAuth 2 is a protocol that allows applications to request access tokens from a security token service and use them to communicate with APIs. Это делегирование снижает сложность в клиентские приложения и интерфейсы API, так как можно быть централизованной проверки подлинности и авторизации.This delegation reduces complexity in both client applications and APIs since authentication and authorization can be centralized.

Сочетание OpenID Connect и OAuth 2.0 объединить две проблемы основополагающих принципов обеспечения безопасности проверки подлинности и доступа к API и IdentityServer 4 представляет собой реализацию этих протоколов.The combination of OpenID Connect and OAuth 2.0 combine the two fundamental security concerns of authentication and API access, and IdentityServer 4 is an implementation of these protocols.

В приложениях, использующих прямое взаимодействие клиента с микрослужбой, таких как приложения eShopOnContainers выделенная микрослужба аутентификации выступает в качестве токенов безопасности службы (STS) можно использовать для проверки подлинности пользователей, как показано на рис. 9-1.In applications that use direct client-to-microservice communication, such as the eShopOnContainers reference application, a dedicated authentication microservice acting as a Security Token Service (STS) can be used to authenticate users, as shown in Figure 9-1. Дополнительные сведения о прямое взаимодействие клиента с микрослужбой, см. в разделе обмен данными между клиентом и Микрослужб.For more information about direct client-to-microservice communication, see Communication Between Client and Microservices.

Рис. 9-1. Проверка подлинности с выделенная микрослужба аутентификацииFigure 9-1: Authentication by a dedicated authentication microservice

В мобильном приложении eShopOnContainers взаимодействует с микрослужбы по идентификации, который использует 4 identityserver должно выполнять проверку подлинности и контроль доступа для интерфейсов API.The eShopOnContainers mobile app communicates with the identity microservice, which uses IdentityServer 4 to perform authentication, and access control for APIs. Таким образом мобильное приложение запрашивает маркеры у IdentityServer, для проверки подлинности пользователя или для доступа к ресурсу:Therefore, the mobile app requests tokens from IdentityServer, either for authenticating a user or for accessing a resource:

  • Проверка подлинности пользователей с identityserver должно достигается запросив мобильное приложение удостоверений маркер, который представляет результат процесса проверки подлинности.Authenticating users with IdentityServer is achieved by the mobile app requesting an identity token, which represents the outcome of an authentication process. Минимум он содержит идентификатор пользователя и сведения о том, как и когда пользователь прошел проверку подлинности.At a bare minimum, it contains an identifier for the user, and information about how and when the user authenticated. Он также может содержать дополнительные идентификационных данных.It can also contain additional identity data.
  • Доступ к ресурсу с identityserver должно достигается запросив мобильное приложение доступа маркер, который разрешает доступ к ресурсу API.Accessing a resource with IdentityServer is achieved by the mobile app requesting an access token, which allows access to an API resource. Клиенты, запроса маркеров доступа и пересылать их в API.Clients request access tokens and forward them to the API. Маркеры доступа содержат сведения о клиенте и пользователь (при его наличии).Access tokens contain information about the client, and the user (if present). API-интерфейсы, затем использовать эту информацию для авторизации доступа к их данным.APIs then use that information to authorize access to their data.

Примечание

Клиента должен быть зарегистрирован с identityserver должно, прежде чем он может запрашивать маркеры.A client must be registered with IdentityServer before it can request tokens.

Добавление IdentityServer веб-приложениеAdding IdentityServer to a Web Application

Чтобы веб-приложение ASP.NET Core для использования IdentityServer 4 его необходимо добавить в решение Visual Studio веб-приложения.In order for an ASP.NET Core web application to use IdentityServer 4, it must be added to the web application's Visual Studio solution. Дополнительные сведения см. в разделе Обзор в документации по IdentityServer.For more information, see Overview in the IdentityServer documentation.

После IdentityServer включен в решение Visual Studio веб-приложения, его необходимо добавить в конвейер обработки запросов HTTP для веб-приложения, чтобы она может выполнять запросы к конечным точкам OpenID Connect и OAuth 2.0.Once IdentityServer is included in the web application's Visual Studio solution, it must be added to the web application's HTTP request processing pipeline, so that it can serve requests to OpenID Connect and OAuth 2.0 endpoints. Это можно сделать в Configure метод веб-приложения Startup класса, как показано в следующем примере кода:This is achieved in the Configure method in the web application's Startup class, as demonstrated in the following code example:

public void Configure(  
    IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)  
{  
    ...  
    app.UseIdentity();  
    ...  
}

Порядок имеет значение в конвейер обработки запросов HTTP для веб-приложения.Order matters in the web application's HTTP request processing pipeline. Таким образом IdentityServer должны добавляться в конвейер, прежде чем платформа пользовательского интерфейса, который реализует экран входа.Therefore, IdentityServer must be added to the pipeline before the UI framework that implements the login screen.

Настройка IdentityServerConfiguring IdentityServer

IdentityServer должно быть настроено в ConfigureServices метод веб-приложения Startup класс путем вызова services.AddIdentityServer метод, как показано в следующем примере кода из эталонного приложения eShopOnContainers:IdentityServer should be configured in the ConfigureServices method in the web application's Startup class by calling the services.AddIdentityServer method, as demonstrated in the following code example from the eShopOnContainers reference application:

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>();  
}

После вызова метода services.AddIdentityServer метод, настройте следующие компоненты называются дополнительные текучего API:After calling the services.AddIdentityServer method, additional fluent APIs are called to configure the following:

  • Учетные данные, используемые для подписывания.Credentials used for signing.
  • Ресурсы API и удостоверений, которые пользователи могут запрашивать доступ к.API and identity resources that users might request access to.
  • Клиенты, которые будут подключаться для запроса маркеров.Clients that will be connecting to request tokens.
  • Удостоверение ASP.NET Core.ASP.NET Core Identity.

Совет

Динамически Загрузите конфигурацию IdentityServer 4.Dynamically load the IdentityServer 4 configuration. IdentityServer 4 API-интерфейсы позволяют настроить сервер из списка в памяти объектов конфигурации.IdentityServer 4's APIs allow for configuring IdentityServer from an in-memory list of configuration objects. В образце приложения eShopOnContainers этих коллекций в памяти жестко запрограммированы в приложение.In the eShopOnContainers reference application, these in-memory collections are hard-coded into the application. Тем не менее в рабочих сценариях их можно загрузить динамически из файла конфигурации или из базы данных.However, in production scenarios they can be loaded dynamically from a configuration file or from a database.

Сведения о настройке identityserver должно использовать удостоверения ASP.NET Core, см. в разделе с помощью ASP.NET Core Identity в документации по IdentityServer.For information about configuring IdentityServer to use ASP.NET Core Identity, see Using ASP.NET Core Identity in the IdentityServer documentation.

Настройка ресурсов APIConfiguring API Resources

При настройке ресурсов API AddInMemoryApiResources ожидает, что метод IEnumerable<ApiResource> коллекции.When configuring API resources, the AddInMemoryApiResources method expects an IEnumerable<ApiResource> collection. В следующем коде показано в примере GetApis метод, который содержит эту коллекцию на eShopOnContainers обращение к приложению:The following code example shows the GetApis method that provides this collection in the eShopOnContainers reference application:

public static IEnumerable<ApiResource> GetApis()  
{  
    return new List<ApiResource>  
    {  
        new ApiResource("orders", "Orders Service"),  
        new ApiResource("basket", "Basket Service")  
    };  
}

Этот метод указывает, что сервер следует защитить, заказов и корзины API-интерфейсы.This method specifies that IdentityServer should protect the orders and basket APIs. Таким образом, IdentityServer управляемый доступ маркеры будут необходимы при выполнении вызовов к этим API.Therefore, IdentityServer managed access tokens will be required when making calls to these APIs. Дополнительные сведения о ApiResource введите, см. в разделе ресурса API в документации по IdentityServer 4.For more information about the ApiResource type, see API Resource in the IdentityServer 4 documentation.

Настройка идентификаторов ресурсовConfiguring Identity Resources

При настройке ресурсов удостоверений AddInMemoryIdentityResources ожидает, что метод IEnumerable<IdentityResource> коллекции.When configuring identity resources, the AddInMemoryIdentityResources method expects an IEnumerable<IdentityResource> collection. Ресурсы удостоверений — это данные, например идентификатор пользователя, имя или адрес электронной почты.Identity resources are data such as user ID, name, or email address. Каждый ресурс удостоверений имеет уникальное имя и произвольных утверждений можно назначить типы, которые будут включены в маркер идентификации для пользователя.Each identity resource has a unique name, and arbitrary claim types can be assigned to it, which will then be included in the identity token for the user. В следующем коде показано в примере GetResources метод, который содержит эту коллекцию на eShopOnContainers обращение к приложению:The following code example shows the GetResources method that provides this collection in the eShopOnContainers reference application:

public static IEnumerable<IdentityResource> GetResources()  
{  
    return new List<IdentityResource>  
    {  
        new IdentityResources.OpenId(),  
        new IdentityResources.Profile()  
    };  
}

Спецификации OpenID Connect описывает некоторые ресурсы стандартные удостоверения.The OpenID Connect specification specifies some standard identity resources. Минимальным требованием является то, что поддержка предоставляется для выдачи уникальный идентификатор для пользователей.The minimum requirement is that support is provided for emitting a unique ID for users. Это достигается путем предоставления IdentityResources.OpenId ресурс идентификаторов.This is achieved by exposing the IdentityResources.OpenId identity resource.

Примечание

IdentityResources Класс поддерживает все области, определенные в спецификации OpenID Connect (openid, электронной почты, профиль, телефона и адрес).The IdentityResources class supports all of the scopes defined in the OpenID Connect specification (openid, email, profile, telephone, and address).

IdentityServer также поддерживает определение пользовательских удостоверений ресурсов.IdentityServer also supports defining custom identity resources. Дополнительные сведения см. в разделе определение пользовательских удостоверений ресурсов в документации по IdentityServer.For more information, see Defining custom identity resources in the IdentityServer documentation. Дополнительные сведения о IdentityResource введите, см. в разделе ресурс идентификаторов в документации по IdentityServer 4.For more information about the IdentityResource type, see Identity Resource in the IdentityServer 4 documentation.

Настройка клиентовConfiguring Clients

Клиенты являются приложениями, которые может запрашивать маркеры из IdentityServer.Clients are applications that can request tokens from IdentityServer. Как правило следующие параметры должны быть определены для каждого клиента как минимум:Typically, the following settings must be defined for each client as a minimum:

  • Идентификатор уникального клиента.A unique client ID.
  • Разрешенные взаимодействия со службой маркеров (известный как тип предоставления).The allowed interactions with the token service (known as the grant type).
  • Расположение, где отправляются токены идентификации и доступа (известный как URI перенаправления).The location where identity and access tokens are sent to (known as a redirect URI).
  • Список ресурсов, которые клиент может получить доступ к (известный как области).A list of resources that the client is allowed access to (known as scopes).

При настройке клиентов, AddInMemoryClients ожидает, что метод IEnumerable<Client> коллекции.When configuring clients, the AddInMemoryClients method expects an IEnumerable<Client> collection. В следующем примере кода показана конфигурация для мобильного приложения eShopOnContainers в GetClients метод, который содержит эту коллекцию на eShopOnContainers обращение к приложению:The following code example shows the configuration for the eShopOnContainers mobile app in the GetClients method that provides this collection in the eShopOnContainers reference application:

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
        },
        ...
    };
}

Эта конфигурация указывает данные для следующих свойств:This configuration specifies data for the following properties:

  • ClientId: Уникальный идентификатор для клиента.ClientId: A unique ID for the client.
  • ClientName: Отображаемое имя клиента, который используется для ведения журнала и на экране согласия.ClientName: The client display name, which is used for logging and the consent screen.
  • AllowedGrantTypes: Указывает, как клиент хочет взаимодействие с identityserver должно.AllowedGrantTypes: Specifies how a client wants to interact with IdentityServer. Дополнительные сведения см. в разделе Настройка поток проверки подлинности.For more information see Configuring the Authentication Flow.
  • ClientSecrets: Задает учетные данные секрета клиента, которые используются при запросе маркеров от конечной точки маркеров.ClientSecrets: Specifies the client secret credentials that are used when requesting tokens from the token endpoint.
  • RedirectUris: Указывает допустимый URI, к которым для возврата маркеров или коды авторизации.RedirectUris: Specifies the allowed URIs to which to return tokens or authorization codes.
  • RequireConsent: Указывает, требуется ли экран согласия.RequireConsent: Specifies whether a consent screen is required.
  • RequirePkce: Признак того, клиенты, использующие код авторизации отправки ключа проверки.RequirePkce: Specifies whether clients using an authorization code must send a proof key.
  • PostLogoutRedirectUris: Указывает URI, чтобы выполнить перенаправление после выхода.PostLogoutRedirectUris: Specifies the allowed URIs to redirect to after logout.
  • AllowedCorsOrigins: Указывает источник, клиента, таким образом, сервер может разрешить вызовы независимо от источника от начала координат.AllowedCorsOrigins: Specifies the origin of the client so that IdentityServer can allow cross-origin calls from the origin.
  • AllowedScopes: Указывает ресурсы, к которым клиент имеет доступ.AllowedScopes: Specifies the resources the client has access to. По умолчанию клиент не имеет доступа к любым ресурсам.By default, a client has no access to any resources.
  • AllowOfflineAccess: Указывает, может ли клиент запрашивать маркеры обновления.AllowOfflineAccess: Specifies whether the client can request refresh tokens.

Настройка потока проверки подлинностиConfiguring the Authentication Flow

Поток проверки подлинности между клиентом и IdentityServer можно настроить, указав типов предоставления разрешения в Client.AllowedGrantTypes свойство.The authentication flow between a client and IdentityServer can be configured by specifying the grant types in the Client.AllowedGrantTypes property. Спецификации OpenID Connect и OAuth 2.0 определить количество потоков аутентификации, включая:The OpenID Connect and OAuth 2.0 specifications define a number of authentication flows, including:

  • Неявные.Implicit. Этот поток оптимизирован для приложений на основе браузера и должен использоваться для пользователя только для проверки подлинности, или запросы маркеров проверки подлинности и доступа.This flow is optimized for browser-based applications and should be used either for user authentication-only, or authentication and access token requests. Все маркеры при передаче через браузер и поэтому дополнительные возможности, например маркеры обновления не разрешены.All tokens are transmitted via the browser, and therefore advanced features like refresh tokens are not permitted.
  • Код авторизации.Authorization code. Этот поток обеспечивает возможность получать токены от через обратный канал, в отличие от внешнего канала браузера, то же время также поддерживает проверку подлинности клиента.This flow provides the ability to retrieve tokens on a back channel, as opposed to the browser front channel, while also supporting client authentication.
  • Гибридный.Hybrid. Этот поток представляет собой сочетание неявный и типы предоставления кода авторизации.This flow is a combination of the implicit and authorization code grant types. Маркер идентификации передается по каналу браузера и содержит ответ со знаком протокола, а также другие артефакты, такие как код авторизации.The identity token is transmitted via the browser channel and contains the signed protocol response along with other artifacts such as the authorization code. После успешной проверки ответа обратного канала должен использоваться для получения доступа и токена обновления.After successful validation of the response, the back channel should be used to retrieve the access and refresh token.

Совет

Используйте гибридный поток проверки подлинности.Use the hybrid authentication flow. Поток проверки подлинности гибридного снижает количество атак, применимые к каналу браузера и является рекомендуемый рабочий процесс для собственных приложений, которые нужно получить маркеры доступа (и возможно для маркеров обновления).The hybrid authentication flow mitigates a number of attacks that apply to the browser channel, and is the recommended flow for native applications that want to retrieve access tokens (and possibly refresh tokens).

Дополнительные сведения о потоках проверки подлинности см. в разделе типы предоставления в документации по IdentityServer 4.For more information about authentication flows, see Grant Types in the IdentityServer 4 documentation.

Выполнение проверки подлинностиPerforming Authentication

Для IdentityServer для выдачи маркеров от имени пользователя пользователь должен войти в к IdentityServer.For IdentityServer to issue tokens on behalf of a user, the user must sign-in to IdentityServer. Тем не менее сервер не предоставляет пользовательский интерфейс или базы данных для проверки подлинности.However, IdentityServer doesn't provide a user interface or database for authentication. Таким образом в образце приложения eShopOnContainers, для этой цели используется удостоверение ASP.NET Core.Therefore, in the eShopOnContainers reference application, ASP.NET Core Identity is used for this purpose.

Мобильное приложение eShopOnContainers использует для проверки подлинности с identityserver должно гибридный поток проверки подлинности, как показано на рисунке 9-2.The eShopOnContainers mobile app authenticates with IdentityServer with the hybrid authentication flow, which is illustrated in Figure 9-2.

Рис. 9-2. Общее представление о процессе входа в системуFigure 9-2: High-level overview of the sign-in process

Сделан запрос входа в систему на <base endpoint>:5105/connect/authorize.A sign-in request is made to <base endpoint>:5105/connect/authorize. После успешной проверки подлинности сервер возвращает ответ проверки подлинности, содержащий код авторизации и токен удостоверения.Following successful authentication, IdentityServer returns an authentication response containing an authorization code and an identity token. Код авторизации затем отправляется <base endpoint>:5105/connect/token, который отвечает с доступом, удостоверения и маркеры обновления.The authorization code is then sent to <base endpoint>:5105/connect/token, which responds with access, identity, and refresh tokens.

EShopOnContainers мобильное приложение знаки готовой IdentityServer, отправив запрос на <base endpoint>:5105/connect/endsession, с дополнительными параметрами.The eShopOnContainers mobile app signs-out of IdentityServer by sending a request to <base endpoint>:5105/connect/endsession, with additional parameters. После выхода, сервер отвечает, отправляя URI перенаправления после выхода мобильное приложение.After sign-out occurs, IdentityServer responds by sending a post logout redirect URI back to the mobile app. Этот процесс показан на рис. 9-3.Figure 9-3 illustrates this process.

Рис. 9-3. Общее представление о процессе выходаFigure 9-3: High-level overview of the sign-out process

В мобильном приложении eShopOnContainers, осуществляется взаимодействие с identityserver должно IdentityService класса, который реализует IIdentityService интерфейс.In the eShopOnContainers mobile app, communication with IdentityServer is performed by the IdentityService class, which implements the IIdentityService interface. Этот интерфейс определяет, что реализующий класс должен предоставить CreateAuthorizationRequest, CreateLogoutRequest, и GetTokenAsync методы.This interface specifies that the implementing class must provide CreateAuthorizationRequest, CreateLogoutRequest, and GetTokenAsync methods.

Вход в системуSigning-in

Когда пользователь касается входа кнопку LoginView, SignInCommand в LoginViewModel выполняется класс, который в свою очередь выполняет SignInAsync метод.When the user taps the LOGIN button on the LoginView, the SignInCommand in the LoginViewModel class is executed, which in turn executes the SignInAsync method. Этот метод показан в следующем примере кода:The following code example shows this method:

private async Task SignInAsync()  
{  
    ...  
    LoginUrl = _identityService.CreateAuthorizationRequest();  
    IsLogin = true;  
    ...  
}

Этот метод вызывает CreateAuthorizationRequest метод в IdentityService класс, который показан в следующем примере кода:This method invokes the CreateAuthorizationRequest method in the IdentityService class, which is shown in the following code example:

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.IdentityCallback);
    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;
}

Этот метод создает URI для элемента IdentityServer конечная точка авторизации, с необходимыми аргументами.This method creates the URI for IdentityServer's authorization endpoint, with the required parameters. Конечная точка авторизации находится в /connect/authorize на порте 5105 базовый конечной точки в виде параметра пользователя.The authorization endpoint is at /connect/authorize on port 5105 of the base endpoint exposed as a user setting. Дополнительные сведения о пользовательских параметрах см. в разделе управления конфигурацией.For more information about user settings, see Configuration Management.

Примечание

Уязвимость в мобильном приложении eShopOnContainers уменьшается путем реализации ключа проверки для обмена кодом (PKCE) расширения OAuth.The attack surface of the eShopOnContainers mobile app is reduced by implementing the Proof Key for Code Exchange (PKCE) extension to OAuth. PKCE защищает код авторизации используется, если оно перехватывается.PKCE protects the authorization code from being used if it’s intercepted. Это достигается путем создания секрета verifier, хэш которого передается в запросе на авторизацию, клиент и представленное нехешированной при активации код авторизации.This is achieved by the client generating a secret verifier, a hash of which is passed in the authorization request, and which is presented unhashed when redeeming the authorization code. Дополнительные сведения о PKCE, см. в разделе ключ подтверждения для кода Exchange с общедоступных клиентов OAuth веб-сайте Internet Engineering Task Force.For more information about PKCE, see Proof Key for Code Exchange by OAuth Public Clients on the Internet Engineering Task Force web site.

Полученный URI хранится в LoginUrl свойство LoginViewModel класса.The returned URI is stored in the LoginUrl property of the LoginViewModel class. Когда IsLogin свойство становится true, WebView в LoginView становится видимым.When the IsLogin property becomes true, the WebView in the LoginView becomes visible. WebView Осуществляет привязку данных его Source свойства LoginUrl свойство LoginViewModel класса и поэтому IdentityServer отправляет запрос входа в систему при LoginUrl свойство имеет значение В IdentityServer конечной точки авторизации.The WebView data binds its Source property to the LoginUrl property of the LoginViewModel class, and so makes a sign-in request to IdentityServer when the LoginUrl property is set to IdentityServer's authorization endpoint. Когда сервер получает этот запрос, и пользователь не прошел проверку подлинности, WebView будете перенаправлены на страницу настроенного входа, как показано на рисунке 9-4.When IdentityServer receives this request and the user isn't authenticated, the WebView will be redirected to the configured login page, which is shown in Figure 9-4.

Рис. 9-4. Страница входа, отображаемого элементом веб-представленияFigure 9-4: Login page displayed by the WebView

После завершения входа WebView будут перенаправляться в возвращаемое URI.Once login is completed, the WebView will be redirected to a return URI. Это WebView навигации приведет к NavigateAsync метод в LoginViewModel класса для выполнения, как показано в следующем примере кода:This WebView navigation will cause the NavigateAsync method in the LoginViewModel class to be executed, which is shown in the following code example:

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();  
        }  
    }  
    ...  
}

Этот метод выполняет синтаксический анализ, содержащийся в URI, возвращаемый ответ проверки подлинности, и при условии, что присутствует код авторизации, оно отправляет запрос к IdentityServer конечная точка маркера, передавая код авторизации, Средство проверки PKCE для секрета и другие необходимые параметры.This method parses the authentication response that's contained in the return URI, and provided that a valid authorization code is present, it makes a request to IdentityServer's token endpoint, passing the authorization code, the PKCE secret verifier, and other required parameters. Конечная точка маркера находится в /connect/token на порте 5105 базовый конечной точки в виде параметра пользователя.The token endpoint is at /connect/token on port 5105 of the base endpoint exposed as a user setting. Дополнительные сведения о пользовательских параметрах см. в разделе управления конфигурацией.For more information about user settings, see Configuration Management.

Совет

Проверка возвращаемого значения идентификаторы URI.Validate return URIs. Несмотря на то, что в мобильном приложении eShopOnContainers не проверяет возвращаемое URI, рекомендуется проверить, что возвращаемое URI ссылается на известном расположении, для предотвращения атак открытого перенаправления.Although the eShopOnContainers mobile app doesn't validate the return URI, the best practice is to validate that the return URI refers to a known location, to prevent open-redirect attacks.

Если конечная точка маркера получает код авторизации и проверки секретный PKCE, он отвечает маркер доступа, маркер идентификации и маркер обновления.If the token endpoint receives a valid authorization code and PKCE secret verifier, it responds with an access token, identity token, and refresh token. Маркер доступа (который предоставляет доступ к ресурсам API) и маркер затем сохраняются как параметры приложения, и выполняется переход по страницам.The access token (which allows access to API resources) and identity token are then stored as application settings, and page navigation is performed. Таким образом, общий эффект в мобильном приложении eShopOnContainers это: при условии, что пользователи могут успешно пройти проверку подлинности с identityserver должно, переходе к MainView страница, которая является TabbedPage отображающий CatalogView как его выбранной вкладки.Therefore, the overall effect in the eShopOnContainers mobile app is this: provided that users are able to successfully authenticate with IdentityServer, they are navigated to the MainView page, which is a TabbedPage that displays the CatalogView as its selected tab.

Сведения о навигации по страницам, см. в разделе навигации.For information about page navigation, see Navigation. Сведения о том, как WebView навигации вызывает метод модели представления для выполнения, см. в разделе вызова навигации с помощью поведений.For information about how WebView navigation causes a view model method to be executed, see Invoking Navigation using Behaviors. Сведения о параметрах приложения см. в разделе управления конфигурацией.For information about application settings, see Configuration Management.

Примечание

EShopOnContainers также позволяет макетов вход, если приложение настроено для использования макеты служб в SettingsView.The eShopOnContainers also allows a mock sign-in when the app is configured to use mock services in the SettingsView. В этом режиме приложения не взаимодействуют с IdentityServer, вместо этого, позволяя пользователю вход с использованием учетных данных.In this mode, the app doesn't communicate with IdentityServer, instead allowing the user to sign-in using any credentials.

Подписывание развертыванияSigning-out

Когда пользователь касается Выход кнопку ProfileView, LogoutCommand в ProfileViewModel выполняется класс, который в свою очередь выполняет LogoutAsync метод.When the user taps the LOG OUT button in the ProfileView, the LogoutCommand in the ProfileViewModel class is executed, which in turn executes the LogoutAsync method. Этот метод выполняет навигацию по страницам для LoginView страницы, передав LogoutParameter экземпляр значение true как параметр.This method performs page navigation to the LoginView page, passing a LogoutParameter instance set to true as a parameter. Дополнительные сведения о передаче параметров во время навигации по страницам см. в разделе передачи параметров во время навигации.For more information about passing parameters during page navigation, see Passing Parameters During Navigation.

При создании представления и осуществлен переход, InitializeAsync связанное представление модели представления метода, который затем выполняет Logout метод LoginViewModel класс, который показан в следующем примере кода:When a view is created and navigated to, the InitializeAsync method of the view's associated view model is executed, which then executes the Logout method of the LoginViewModel class, which is shown in the following code example:

private void Logout()  
{  
    var authIdToken = Settings.AuthIdToken;  
    var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);  

    if (!string.IsNullOrEmpty(logoutRequest))  
    {  
        // Logout  
        LoginUrl = logoutRequest;  
    }  
    ...  
}

Этот метод вызывает CreateLogoutRequest метод в IdentityService класса, передавая маркер идентификации, полученные из параметров приложения, как параметр.This method invokes the CreateLogoutRequest method in the IdentityService class, passing the identity token retrieved from application settings as a parameter. Дополнительные сведения о параметрах приложения см. в разделе управления конфигурацией.For more information about application settings, see Configuration Management. Метод CreateLogoutRequest показан в следующем примере кода:The following code example shows the CreateLogoutRequest method:

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);  
}

Этот метод создает URI для элемента IdentityServer завершить сеанс конечной точки, с необходимыми аргументами.This method creates the URI to IdentityServer's end session endpoint, with the required parameters. Конечная точка окончания сеанса находится в /connect/endsession на порте 5105 базовый конечной точки в виде параметра пользователя.The end session endpoint is at /connect/endsession on port 5105 of the base endpoint exposed as a user setting. Дополнительные сведения о пользовательских параметрах см. в разделе управления конфигурацией.For more information about user settings, see Configuration Management.

Полученный URI хранится в LoginUrl свойство LoginViewModel класса.The returned URI is stored in the LoginUrl property of the LoginViewModel class. Хотя IsLogin свойство true, WebView в LoginView является видимым.While the IsLogin property is true, the WebView in the LoginView is visible. WebView Осуществляет привязку данных его Source свойства LoginUrl свойство LoginViewModel класса и поэтому запрос выхода для IdentityServer при LoginUrl свойство имеет значение В IdentityServer конечной сеанса.The WebView data binds its Source property to the LoginUrl property of the LoginViewModel class, and so makes a sign-out request to IdentityServer when the LoginUrl property is set to IdentityServer's end session endpoint. Когда сервер получает этот запрос, при условии, что пользователь, выполнивший вход, происходит выход.When IdentityServer receives this request, provided that the user is signed-in, sign-out occurs. Проверка подлинности отслеживается с файлом cookie, управляемых по промежуточного слоя проверки подлинности файла cookie из ASP.NET Core.Authentication is tracked with a cookie managed by the cookie authentication middleware from ASP.NET Core. Таким образом выйдя из IdentityServer удаляет файл cookie проверки подлинности и отправляет перенаправления после выхода, URI обратно клиенту.Therefore, signing out of IdentityServer removes the authentication cookie and sends a post logout redirect URI back to the client.

В мобильном приложении WebView будут перенаправляться в URI перенаправления после выхода.In the mobile app, the WebView will be redirected to the post logout redirect URI. Это WebView навигации приведет к NavigateAsync метод в LoginViewModel класса для выполнения, как показано в следующем примере кода:This WebView navigation will cause the NavigateAsync method in the LoginViewModel class to be executed, which is shown in the following code example:

private async Task NavigateAsync(string url)  
{  
    ...  
    Settings.AuthAccessToken = string.Empty;  
    Settings.AuthIdToken = string.Empty;  
    IsLogin = false;  
    LoginUrl = _identityService.CreateAuthorizationRequest();  
    ...  
}

Этот метод удаляет маркер идентификации и маркер доступа из параметров приложения и задает IsLogin свойства false, чего WebView на LoginView страница станет невидимой .This method clears both the identity token and the access token from application settings, and sets the IsLogin property to false, which causes the WebView on the LoginView page to become invisible. Наконец LoginUrl свойству IdentityServer URI из конечная точка авторизации, с необходимыми аргументами, в процессе подготовки в следующий раз, когда пользователь инициирует вход в систему.Finally, the LoginUrl property is set to the URI of IdentityServer's authorization endpoint, with the required parameters, in preparation for the next time the user initiates a sign-in.

Сведения о навигации по страницам, см. в разделе навигации.For information about page navigation, see Navigation. Сведения о том, как WebView навигации вызывает метод модели представления для выполнения, см. в разделе вызова навигации с помощью поведений.For information about how WebView navigation causes a view model method to be executed, see Invoking Navigation using Behaviors. Сведения о параметрах приложения см. в разделе управления конфигурацией.For information about application settings, see Configuration Management.

Примечание

EShopOnContainers также позволяет макетирование выхода при настройке приложения для использования в SettingsView макеты служб.The eShopOnContainers also allows a mock sign-out when the app is configured to use mock services in the SettingsView. В этом режиме приложение не взаимодействует с identityserver должно и вместо очищает все хранимые токены из параметров приложения.In this mode, the app doesn't communicate with IdentityServer, and instead clears any stored tokens from application settings.

АвторизацияAuthorization

После проверки подлинности веб-ASP.NET Core, часто требуется API-интерфейсы для разрешения доступа, что позволяет службе предоставить интерфейсы API доступны некоторые пользователям, прошедшим проверку, но не всем.After authentication, ASP.NET Core web APIs often need to authorize access, which allows a service to make APIs available to some authenticated users, but not to all.

Ограничение доступа к маршруту ASP.NET Core MVC может осуществляться путем применения атрибута Authorize к контроллеру или действие, которое ограничивает доступ к контроллеру или действие, прошедшим проверку подлинности, как показано в следующем примере кода:Restricting access to an ASP.NET Core MVC route can be achieved by applying an Authorize attribute to a controller or action, which limits access to the controller or action to authenticated users, as shown in the following code example:

[Authorize]  
public class BasketController : Controller  
{  
    ...  
}

Если неавторизованный пользователь пытается получить доступ к контроллеру или действию, отмеченный атрибутом Authorize атрибут, платформа MVC возвращает код состояния 401 (неавторизованный) HTTP.If an unauthorized user attempts to access a controller or action that's marked with the Authorize attribute, the MVC framework returns a 401 (unauthorized) HTTP status code.

Примечание

Параметры могут быть заданы на Authorize атрибута для ограничения API для определенных пользователей.Parameters can be specified on the Authorize attribute to restrict an API to specific users. Дополнительные сведения см. в разделе авторизации.For more information, see Authorization.

IdentityServer можно интегрировать в рабочий процесс авторизации, чтобы маркеры доступа, он предоставляет контроль авторизации.IdentityServer can be integrated into the authorization workflow so that the access tokens it provides control authorization. Этот подход показан на рисунке 9-5.This approach is shown in Figure 9-5.

Рис. 9-5. Авторизация с использованием маркера доступаFigure 9-5: Authorization by access token

В мобильном приложении eShopOnContainers взаимодействует с микрослужбы по идентификации и запрашивает маркер доступа как часть процесса проверки подлинности.The eShopOnContainers mobile app communicates with the identity microservice and requests an access token as part of the authentication process. Маркер доступа, перенаправляется API, предоставляемых микрослужб упорядочения и корзины как часть запросов на доступ.The access token is then forwarded to the APIs exposed by the ordering and basket microservices as part of the access requests. Маркеры доступа содержат информацию о клиенте и пользователь.Access tokens contain information about the client, and the user. API-интерфейсы, затем использовать эту информацию для авторизации доступа к их данным.APIs then use that information to authorize access to their data. Сведения о том, как настроить сервер для защиты API-интерфейсов, см. в разделе Настройка ресурсов API.For information about how to configure IdentityServer to protect APIs, see Configuring API Resources.

Настройка IdentityServer выполнение авторизацииConfiguring IdentityServer to Perform Authorization

Выполнение авторизации с identityserver должно, необходимо добавить его авторизации по промежуточного слоя конвейер запросов HTTP веб-приложения.To perform authorization with IdentityServer, its authorization middleware must be added to the web application's HTTP request pipeline. По промежуточного слоя добавляется в ConfigureAuth метод веб-приложения Startup класс, который вызывается из Configure метод и демонстрируется в следующем примере кода из эталонного приложения eShopOnContainers:The middleware is added in the ConfigureAuth method in the web application's Startup class, which is invoked from the Configure method, and is demonstrated in the following code example from the eShopOnContainers reference application:

protected virtual void ConfigureAuth(IApplicationBuilder app)  
{  
    var identityUrl = Configuration.GetValue<string>("IdentityUrl");  
    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions  
    {  
        Authority = identityUrl.ToString(),  
        ScopeName = "basket",  
        RequireHttpsMetadata = false  
    });  
} 

Этот метод гарантирует, что API может осуществляться только с действительный маркер доступа.This method ensures that the API can only be accessed with a valid access token. По промежуточного слоя проверяет входящий токен, чтобы убедиться, что оно отправлено с надежным издателем и проверяет, что маркер является допустимым для использования с API, которая его получает.The middleware validates the incoming token to ensure that it's sent from a trusted issuer, and validates that the token is valid to be used with the API that receives it. Таким образом перейдя к контроллеру упорядочение или корзины вернет (несанкционированных) код состояния HTTP 401, указывающее, что маркер доступа является обязательным.Therefore, browsing to the ordering or basket controller will return a 401 (unauthorized) HTTP status code, indicating that an access token is required.

Примечание

По промежуточного слоя сервер авторизации необходимо добавить в конвейер запросов HTTP веб-приложения перед добавлением MVC с app.UseMvc() или app.UseMvcWithDefaultRoute().IdentityServer's authorization middleware must be added to the web application's HTTP request pipeline before adding MVC with app.UseMvc() or app.UseMvcWithDefaultRoute().

Создание запросов на доступ к интерфейсам APIMaking Access Requests to APIs

При составлении запросов к микрослужб упорядочения и корзины, доступ маркер, полученный из IdentityServer во время процесса проверки подлинности, должны быть включены в запрос, как показано в следующем примере кода:When making requests to the ordering and basket microservices, the access token, obtained from IdentityServer during the authentication process, must be included in the request, as shown in the following code example:

var authToken = Settings.AuthAccessToken;  
Order = await _ordersService.GetOrderAsync(Convert.ToInt32(order.OrderNumber), authToken);

Маркер доступа хранится в виде параметра приложения и получить из хранилища с платформой и включены в вызове GetOrderAsync метод в OrderService класса.The access token is stored as an application setting, and is retrieved from platform-specific storage and included in the call to the GetOrderAsync method in the OrderService class.

Аналогичным образом маркер доступа должен быть включен при отправке данных IdentityServer защите API, как показано в следующем примере кода:Similarly, the access token must be included when sending data to an IdentityServer protected API, as shown in the following code example:

var authToken = Settings.AuthAccessToken;  
await _basketService.UpdateBasketAsync(new CustomerBasket  
{  
    BuyerId = userInfo.UserId,   
    Items = BasketItems.ToList()  
}, authToken);

Маркер доступа извлекается из хранилища, зависящее от платформы и включены в вызове UpdateBasketAsync метод в BasketService класса.The access token is retrieved from platform-specific storage and included in the call to the UpdateBasketAsync method in the BasketService class.

RequestProvider Класс, в мобильном приложении eShopOnContainers, использует HttpClient класса для выполнения запросов к API-интерфейсов RESTful, предоставляемые в образце приложения eShopOnContainers.The RequestProvider class, in the eShopOnContainers mobile app, uses the HttpClient class to make requests to the RESTful APIs exposed by the eShopOnContainers reference application. При отправке запросов в заказ и корзины API-интерфейсы, которые требуют наличия авторизации, действительный маркер доступа должен быть включен в запрос.When making requests to the ordering and basket APIs, which require authorization, a valid access token must be included with the request. Это достигается путем добавления маркера доступа к заголовкам HttpClient экземпляра, как показано в следующем примере кода:This is achieved by adding the access token to the headers of the HttpClient instance, as demonstrated in the following code example:

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

DefaultRequestHeaders Свойство HttpClient класс предоставляет заголовки, которые отправляются с каждым запросом, и маркер доступа добавляется Authorization префиксом со строкой заголовка Bearer.The DefaultRequestHeaders property of the HttpClient class exposes the headers that are sent with each request, and the access token is added to the Authorization header prefixed with the string Bearer. Отправки запроса к API-интерфейсов RESTful, значение Authorization извлекается и проверять на соответствие отправляются от доверенного издателя, что позволяет определить, имеет ли пользователь разрешение на вызов API, получает его заголовок.When the request is sent to a RESTful API, the value of the Authorization header is extracted and validated to ensure that it's sent from a trusted issuer, and used to determine whether the user has permission to invoke the API that receives it.

Дополнительные сведения о том, как мобильное приложение eShopOnContainers выполняет веб-запросы, см. в разделе доступ к удаленным данным.For more information about how the eShopOnContainers mobile app makes web requests, see Accessing Remote Data.

СводкаSummary

Существует множество подходов к интеграции проверки подлинности и авторизации в приложение Xamarin.Forms, которое взаимодействует с веб-приложение ASP.NET MVC.There are many approaches to integrating authentication and authorization into a Xamarin.Forms app that communicates with an ASP.NET MVC web application. В мобильном приложении eShopOnContainers выполняет проверку подлинности и авторизации с помощью микрослужбы контейнерных удостоверений, которая использует IdentityServer 4.The eShopOnContainers mobile app performs authentication and authorization with a containerized identity microservice that uses IdentityServer 4. IdentityServer — это платформа с открытым исходным OpenID Connect и OAuth 2.0 для ASP.NET Core, которое интегрируется с удостоверением ASP.NET Core для выполнения проверки подлинности токена носителя.IdentityServer is an open source OpenID Connect and OAuth 2.0 framework for ASP.NET Core that integrates with ASP.NET Core Identity to perform bearer token authentication.

Мобильное приложение запрашивает у IdentityServer, маркеры безопасности, для проверки подлинности пользователя или для доступа к ресурсу.The mobile app requests security tokens from IdentityServer, either for authenticating a user or for accessing a resource. При доступе к ресурсу, маркер доступа должен быть включен в запросе к API, требующие авторизации.When accessing a resource, an access token must be included in the request to APIs that require authorization. По промежуточного слоя сервер проверяет входящие маркеры доступа, чтобы убедиться, что они передаются от доверенного издателя, и что они являются допустимыми для использования с API, который их получает.IdentityServer's middleware validates incoming access tokens to ensure that they are sent from a trusted issuer, and that they are valid to be used with the API that receives them.