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

Примечание.

Эта электронная книга была опубликована весной 2017 года и с тех пор не была обновлена. Есть много в книге, которая остается ценным, но некоторые из материалов устарели.

Проверка подлинности — это процесс получения учетных данных идентификации, таких как имя и пароль пользователя, и проверка этих учетных данных для центра. Если учетные данные действительны, сущность, отправленная учетными данными, считается удостоверением, прошедшим проверку подлинности. После проверки подлинности удостоверения процесс авторизации определяет, имеет ли это удостоверение доступ к указанному ресурсу.

Существует множество подходов к интеграции проверки подлинности и авторизации в Xamarin.Forms приложение, которое взаимодействует с веб-приложением ASP.NET MVC, включая использование ASP.NET Core Identity, внешних поставщиков проверки подлинности, таких как Microsoft, Google, Facebook или Twitter, и по промежуточному слоям проверки подлинности. Мобильное приложение eShopOnContainers выполняет проверку подлинности и авторизацию с помощью контейнерной микрослужбы удостоверений, использующего IdentityServer 4. Мобильное приложение запрашивает маркеры безопасности из IdentityServer либо для проверки подлинности пользователя, либо для доступа к ресурсу. Чтобы IdentityServer выдавал маркеры от имени пользователя, пользователь должен войти в IdentityServer. Однако IdentityServer не предоставляет пользовательский интерфейс или базу данных для проверки подлинности. Поэтому в справочном приложении eShopOnContainers ASP.NET Core Identity используется для этой цели.

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

Проверка подлинности требуется, если приложению необходимо знать удостоверение текущего пользователя. ASP.NET основной механизм идентификации пользователей — это система членства ASP.NET Core Identity, которая хранит сведения о пользователе в хранилище данных, настроенном разработчиком. Как правило, это хранилище данных будет хранилище EntityFramework, хотя пользовательские хранилища или сторонние пакеты можно использовать для хранения сведений об удостоверениях в хранилище Azure, Azure Cosmos DB или других расположениях.

Для сценариев проверки подлинности, использующих локальное хранилище данных пользователей, и сохраняйте сведения об удостоверениях между запросами через файлы cookie (как обычно в веб-приложениях MVC ASP.NET MVC), ASP.NET Core Identity — это подходящее решение. Однако файлы cookie не всегда являются естественным средством сохранения и передачи данных. Например, веб-приложение ASP.NET Core, которое предоставляет конечные точки RESTful, к которым обращается мобильное приложение, обычно потребуется использовать проверку подлинности маркера носителя, так как файлы cookie нельзя использовать в этом сценарии. Однако маркеры носителя можно легко получить и включить в заголовок авторизации веб-запросов, сделанных из мобильного приложения.

Выдача маркеров носителя с помощью IdentityServer 4

IdentityServer 4 — это платформа открытый код OpenID Подключение и OAuth 2.0 для ASP.NET Core, которая может использоваться для многих сценариев проверки подлинности и авторизации, включая выдачу маркеров безопасности для локальных пользователей ASP.NET Core Identity.

Примечание.

OpenID Подключение и OAuth 2.0 очень похожи, хотя и имеют разные обязанности.

OpenID Подключение — это уровень проверки подлинности на вершине протокола OAuth 2.0. OAuth 2 — это протокол, позволяющий приложениям запрашивать маркеры доступа из службы маркеров безопасности и использовать их для взаимодействия с API. Это делегирование снижает сложность как клиентских приложений, так и API, так как проверка подлинности и авторизация могут быть централизованны.

Сочетание OpenID Подключение и OAuth 2.0 объединяет две основные проблемы безопасности для проверки подлинности и доступа к API, а IdentityServer 4 — реализация этих протоколов.

В приложениях, использующих прямое взаимодействие между клиентами и микрослужбами, например эталонное приложение eShopOnContainers, выделенная микрослужба проверки подлинности, выступающая в качестве службы маркеров безопасности (STS), может использоваться для проверки подлинности пользователей, как показано на рис. 9-1. Дополнительные сведения о прямой связи между клиентами и микрослужбами см. в разделе "Обмен данными между клиентами и микрослужбами".

Authentication by a dedicated authentication microservice

Рис. 9-1. Проверка подлинности с помощью выделенной микрослужбы проверки подлинности

Мобильное приложение eShopOnContainers взаимодействует с микрослужбой удостоверений, которая использует IdentityServer 4 для проверки подлинности и управления доступом для API. Таким образом, мобильное приложение запрашивает маркеры из IdentityServer либо для проверки подлинности пользователя, либо для доступа к ресурсу:

  • Проверка подлинности пользователей с помощью IdentityServer достигается мобильным приложением, запрашивающим маркер удостоверения, который представляет результат процесса проверки подлинности . Как минимум, он содержит идентификатор пользователя и сведения о том, как и когда пользователь прошел проверку подлинности. Он также может содержать дополнительные данные удостоверений.
  • Доступ к ресурсу с помощью IdentityServer достигается мобильным приложением, запрашивающим маркер доступа , который позволяет получить доступ к ресурсу API. Клиенты запрашивают маркеры доступа и пересылают их в API. Маркеры доступа содержат сведения о клиенте, а пользователь (при наличии). Затем API используют эти сведения для авторизации доступа к их данным.

Примечание.

Перед запросом маркеров клиент должен быть зарегистрирован в IdentityServer.

Добавление IdentityServer в веб-приложение

Чтобы веб-приложение ASP.NET Core использовало IdentityServer 4, его необходимо добавить в решение Visual Studio веб-приложения. Дополнительные сведения см. в документации по IdentityServer.

После включения IdentityServer в решение Visual Studio веб-приложения его необходимо добавить в конвейер обработки HTTP-запросов веб-приложения, чтобы он смог обслуживать запросы к конечным точкам OpenID Подключение и OAuth 2.0. Это достигается в методе Configure в классе веб-приложения Startup , как показано в следующем примере кода:

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

Порядок имеет значение в конвейере обработки HTTP-запросов веб-приложения. Таким образом, IdentityServer необходимо добавить в конвейер перед платформой пользовательского интерфейса, реализующей экран входа.

Настройка IdentityServer

IdentityServer следует настроить в методе ConfigureServices в классе веб-приложения Startup путем вызова services.AddIdentityServer метода, как показано в следующем примере кода из справочного приложения 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>();  
}

После вызова services.AddIdentityServer метода вызываются дополнительные интерфейсы API fluent, чтобы настроить следующее:

  • Учетные данные, используемые для подписывания.
  • Ресурсы API и удостоверения, к которым пользователи могут запрашивать доступ.
  • Клиенты, которые будут подключаться к маркерам запроса.
  • ASP.NET Core Identity.

Совет

Динамическое загрузка конфигурации IdentityServer 4. API IdentityServer 4 позволяют настроить IdentityServer из списка объектов конфигурации в памяти. В справочном приложении eShopOnContainers эти коллекции в памяти жестко закодируются в приложении. Однако в рабочих сценариях их можно загружать динамически из файла конфигурации или из базы данных.

Сведения о настройке IdentityServer для использования ASP.NET Core Identity см. в документации по IdentityServer с помощью ASP.NET Core Identity .

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

При настройке ресурсов AddInMemoryApiResources API метод ожидает коллекцию IEnumerable<ApiResource> . В следующем примере кода показан GetApis метод, предоставляющий эту коллекцию в справочном приложении eShopOnContainers:

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

Этот метод указывает, что IdentityServer должен защищать API заказов и корзины. Таким образом, маркеры управляемого доступа IdentityServer потребуются при вызове этих API. Дополнительные сведения о типе ApiResource см. в документации по ApiServer 4.

Настройка ресурсов удостоверений

При настройке ресурсов AddInMemoryIdentityResources удостоверений метод ожидает коллекцию IEnumerable<IdentityResource> . Ресурсы удостоверений — это данные, такие как идентификатор пользователя, имя или адрес электронной почты. Каждому ресурсу удостоверений присвоено уникальное имя, и типы произвольных утверждений могут быть назначены ему, которые затем будут включены в маркер удостоверения для пользователя. В следующем примере кода показан GetResources метод, предоставляющий эту коллекцию в справочном приложении eShopOnContainers:

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

Спецификация OpenID Подключение указывает некоторые стандартные ресурсы удостоверений. Минимальное требование заключается в том, что поддержка предоставляется для создания уникального идентификатора для пользователей. Это достигается путем предоставления IdentityResources.OpenId ресурса удостоверений.

Примечание.

Класс IdentityResources поддерживает все область, определенные в спецификации OpenID Подключение (openid, email, profile, телефон и адрес).

IdentityServer также поддерживает определение ресурсов пользовательских удостоверений. Дополнительные сведения о типе IdentityResource см. в документации по IdentityServer 4.

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

Клиенты — это приложения, которые могут запрашивать маркеры из IdentityServer. Как правило, для каждого клиента необходимо определить следующие параметры как минимум:

  • Уникальный идентификатор клиента.
  • Разрешенное взаимодействие со службой маркеров (известное как тип предоставления).
  • Расположение, в котором отправляются маркеры удостоверения и доступа (известный как универсальный код ресурса (URI перенаправления).
  • Список ресурсов, к которым клиент может получить доступ (известный как область).

При настройке клиентов AddInMemoryClients метод ожидает коллекцию IEnumerable<Client> . В следующем примере кода показана конфигурация мобильного приложения eShopOnContainers в методе GetClients , который предоставляет эту коллекцию в справочном приложении 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
        },
        ...
    };
}

Эта конфигурация задает данные для следующих свойств:

  • ClientId: уникальный идентификатор клиента.
  • ClientName: отображаемое имя клиента, которое используется для ведения журнала и экрана согласия.
  • AllowedGrantTypes: указывает, как клиент хочет взаимодействовать с IdentityServer. Дополнительные сведения см. в разделе "Настройка потока проверки подлинности".
  • ClientSecrets: указывает учетные данные секрета клиента, используемые при запросе маркеров из конечной точки токена.
  • RedirectUris: указывает разрешенные URI, к которым возвращаются маркеры или коды авторизации.
  • RequireConsent: указывает, требуется ли экран согласия.
  • RequirePkce: указывает, должны ли клиенты, использующие код авторизации, отправлять ключ подтверждения.
  • PostLogoutRedirectUris: указывает разрешенные URI для перенаправления в после выхода.
  • AllowedCorsOrigins: указывает источник клиента, чтобы IdentityServer могли разрешать вызовы между источниками.
  • AllowedScopes: указывает ресурсы, к к которые клиент имеет доступ. По умолчанию клиент не имеет доступа к каким-либо ресурсам.
  • AllowOfflineAccess: указывает, может ли клиент запрашивать маркеры обновления.

Настройка потока проверки подлинности

Поток проверки подлинности между клиентом и IdentityServer можно настроить, указав типы грантов в свойстве Client.AllowedGrantTypes . Спецификации OpenID Подключение и OAuth 2.0 определяют ряд потоков проверки подлинности, в том числе:

  • Неявные. Этот поток оптимизирован для приложений на основе браузера и должен использоваться только для проверки подлинности пользователей, а также для запросов маркеров доступа и проверки подлинности. Все маркеры передаются через браузер, поэтому расширенные функции, такие как маркеры обновления, не допускаются.
  • Код авторизации. Этот поток обеспечивает возможность получения маркеров на заднем канале, а не внешнего канала браузера, а также поддержки проверки подлинности клиента.
  • Гибридный. Этот поток представляет собой сочетание неявных и типов предоставления кода авторизации. Маркер удостоверения передается через канал браузера и содержит подписанный ответ протокола вместе с другими артефактами, такими как код авторизации. После успешной проверки ответа канал обратной части должен использоваться для получения маркера доступа и обновления.

Совет

Используйте поток гибридной проверки подлинности. Поток гибридной проверки подлинности устраняет ряд атак, которые применяются к каналу браузера, и это рекомендуемый поток для собственных приложений, которые хотят получить маркеры доступа (и, возможно, маркеры обновления).

Дополнительные сведения о потоках проверки подлинности см . в документации по IdentityServer 4.

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

Чтобы IdentityServer выдавал маркеры от имени пользователя, пользователь должен войти в IdentityServer. Однако IdentityServer не предоставляет пользовательский интерфейс или базу данных для проверки подлинности. Поэтому в справочном приложении eShopOnContainers ASP.NET Core Identity используется для этой цели.

Мобильное приложение eShopOnContainers проходит проверку подлинности с помощью IdentityServer с помощью потока гибридной проверки подлинности, который показан на рис. 9-2.

High-level overview of the sign-in process

Рис. 9-2. Общие сведения о процессе входа

Запрос на вход выполняется <base endpoint>:5105/connect/authorize. После успешной проверки подлинности IdentityServer возвращает ответ проверки подлинности, содержащий код авторизации и маркер удостоверения. Затем код авторизации отправляется <base endpoint>:5105/connect/tokenв , в который отвечает маркеры доступа, удостоверения и обновления.

Мобильное приложение eShopOnContainers выходит из IdentityServer, отправляя запрос <base endpoint>:5105/connect/endsessionна использование дополнительных параметров. После выхода IdentityServer отвечает, отправив URI перенаправления после выхода обратно в мобильное приложение. Рис. 9-3 иллюстрирует этот процесс.

High-level overview of the sign-out process

Рис. 9-3. Общие сведения о процессе выхода

В мобильном приложении eShopOnContainers обмен данными с IdentityServer выполняется классом IdentityService , который реализует IIdentityService интерфейс. Этот интерфейс указывает, что реализующий класс должен предоставлять CreateAuthorizationRequestи CreateLogoutRequestGetTokenAsync методы.

Вход

Когда пользователь нажимает кнопку LOGIN на LoginViewобъекте, SignInCommand выполняется класс LoginViewModel , который, в свою очередь, выполняет SignInAsync метод. Этот метод показан в следующем примере кода:

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

Этот метод вызывает CreateAuthorizationRequest метод в IdentityService классе, который показан в следующем примере кода:

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

Этот метод создает универсальный код ресурса (URI) для конечной точки авторизации IdentityServer с необходимыми параметрами. Конечная точка авторизации находится через /connect/authorize порт 5105 базовой конечной точки, предоставляемой в качестве параметра пользователя. Дополнительные сведения о параметрах пользователя см. в разделе "Управление конфигурацией".

Примечание.

Область атаки мобильного приложения eShopOnContainers уменьшается путем реализации расширения Проверки подлинности для Обмена кодом (PKCE) в OAuth. PKCE защищает код авторизации от использования, если он перехватывается. Это достигается клиентом, создающим секретный проверяющий объект, хэш которого передается в запросе авторизации, и который отображается без косой черты при активации кода авторизации. Дополнительные сведения о PKCE см . на веб-сайте Группы задач разработки Интернета в качестве ключа проверки подлинности для обмена кодом от общедоступных клиентов OAuth.

Возвращаемый URI хранится в LoginUrl свойстве LoginViewModel класса. IsLogin Когда свойство становится trueвидимым, WebView он LoginView становится видимым. Данные WebView привязывают его Source свойство к LoginUrl свойству LoginViewModel класса, поэтому выполняет запрос входа в IdentityServer, когда LoginUrl свойство установлено в конечную точку авторизации IdentityServer. Когда IdentityServer получает этот запрос и пользователь не проходит проверку подлинности, WebView он будет перенаправлен на настроенную страницу входа, которая показана на рис. 9-4.

Login page displayed by the WebView

Рис. 9-4. Страница входа, отображаемая webView

После завершения WebView входа вы будете перенаправлены в возвращаемый URI. Эта WebView навигация приведет NavigateAsync к выполнению метода в LoginViewModel классе, который показан в следующем примере кода:

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 и другие обязательные параметры. Конечная точка маркера находится в /connect/token порте 5105 базовой конечной точки, предоставляемой в качестве параметра пользователя. Дополнительные сведения о параметрах пользователя см. в разделе "Управление конфигурацией".

Совет

Проверьте URI возврата. Хотя мобильное приложение eShopOnContainers не проверяет URI возврата, рекомендуется проверить, ссылается ли возвращаемый URI на известное расположение, чтобы предотвратить атаки с открытым перенаправлением.

Если конечная точка маркера получает действительный код авторизации и средство проверки секрета PKCE, он отвечает маркером доступа, маркером идентификации и маркером обновления. Маркер доступа (который позволяет получить доступ к ресурсам API) и маркер удостоверений затем хранятся в качестве параметров приложения, а навигация по страницам выполняется. Таким образом, общий эффект в мобильном приложении eShopOnContainers заключается в следующем: при условии, что пользователи могут успешно пройти проверку подлинности с помощью IdentityServer, они переходят на MainView страницу, которая TabbedPage отображается CatalogView в качестве выбранной вкладки.

Сведения о навигации по страницам см. в разделе "Навигация". Сведения о том, как WebView навигация приводит к выполнению метода модели представления, см. в статье "Вызов навигации с помощью поведения". Сведения о параметрах приложения см. в разделе "Управление конфигурацией".

Примечание.

EShopOnContainers также позволяет выполнять макет входа, когда приложение настроено на использование макетных служб в приложении SettingsView. В этом режиме приложение не взаимодействует с IdentityServer, а позволяет пользователю входить с помощью учетных данных.

Выход

Когда пользователь нажимает кнопку LOG OUT в ProfileViewклассе, LogoutCommandProfileViewModel который, в свою очередь, выполняет LogoutAsync метод. Этот метод выполняет навигацию LoginView по страницам, передав экземпляр, заданный LogoutParameter в true качестве параметра. Дополнительные сведения о передаче параметров во время навигации по страницам см. в разделе "Передача параметров во время навигации".

При создании и переходе InitializeAsync к представлению выполняется метод связанной модели представления представления, который затем выполняет Logout метод LoginViewModel класса, который показан в следующем примере кода:

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

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

Этот метод вызывает CreateLogoutRequest метод в IdentityService классе, передав маркер удостоверения, полученный из параметров приложения в качестве параметра. Дополнительные сведения о параметрах приложения см. в разделе "Управление конфигурацией". Метод 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);  
}

Этот метод создает универсальный код ресурса (URI) для конечной точки сеанса IdentityServer с необходимыми параметрами. Конечная точка сеанса находится в /connect/endsession порте 5105 базовой конечной точки, предоставляемой в качестве параметра пользователя. Дополнительные сведения о параметрах пользователя см. в разделе "Управление конфигурацией".

Возвращаемый URI хранится в LoginUrl свойстве LoginViewModel класса. IsLogin В то время как свойство имеет trueзначение , WebView в ней LoginView отображается. Данные WebView привязывают его Source свойство к свойству LoginViewModel класса, поэтому выполняет запрос выхода к LoginUrl IdentityServer, когда LoginUrl свойство установлено на конечную точку сеанса IdentityServer. Когда IdentityServer получает этот запрос, при условии, что пользователь вошел в систему, происходит выход. Проверка подлинности отслеживается с помощью файла cookie, управляемого ПО промежуточного слоя проверки подлинности cookie из ASP.NET Core. Поэтому выход из IdentityServer удаляет файл cookie проверки подлинности и отправляет URI перенаправления после выхода обратно клиенту.

В мобильном приложении WebView будет перенаправлено в URI перенаправления после выхода. Эта WebView навигация приведет NavigateAsync к выполнению метода в LoginViewModel классе, который показан в следующем примере кода:

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

Этот метод очищает маркер удостоверения и маркер доступа из параметров приложения и задает IsLogin для свойства значение false, которое приводит к тому, что на WebViewLoginView странице становится невидимым. Наконец, LoginUrl для свойства задан универсальный код ресурса (URI) конечной точки авторизации IdentityServer с необходимыми параметрами при подготовке к следующему запуску входа.

Сведения о навигации по страницам см. в разделе "Навигация". Сведения о том, как WebView навигация приводит к выполнению метода модели представления, см. в статье "Вызов навигации с помощью поведения". Сведения о параметрах приложения см. в разделе "Управление конфигурацией".

Примечание.

EShopOnContainers также позволяет выходить из системы, когда приложение настроено использовать макетные службы в Параметры View. В этом режиме приложение не взаимодействует с IdentityServer и вместо этого очищает сохраненные маркеры из параметров приложения.

Авторизация

После проверки подлинности ASP.NET веб-API Core часто требуется авторизовать доступ, что позволяет службе предоставлять доступ к API некоторым пользователям, прошедшим проверку подлинности, но не всем.

Ограничение доступа к маршруту ASP.NET Core MVC можно добиться путем применения атрибута Authorize к контроллеру или действию, который ограничивает доступ к контроллеру или действию для прошедших проверку подлинности пользователей, как показано в следующем примере кода:

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

Если несанкционированный пользователь пытается получить доступ к контроллеру или действию, помеченным Authorize атрибутом, платформа MVC возвращает код состояния HTTP 401 (несанкционированный).

Примечание.

Параметры можно указать в атрибуте Authorize , чтобы ограничить API определенным пользователям. Дополнительные сведения см. в статье об авторизации.

IdentityServer можно интегрировать в рабочий процесс авторизации, чтобы маркеры доступа, обеспечивающие авторизацию управления. Этот подход показан на рис. 9-5.

Authorization by access token

Рис. 9-5. Авторизация по маркеру доступа

Мобильное приложение eShopOnContainers взаимодействует с микрослужбой удостоверений и запрашивает маркер доступа в рамках процесса проверки подлинности. Затем маркер доступа пересылается в API, предоставляемые микрослужбами заказа и корзины в рамках запросов на доступ. Маркеры доступа содержат сведения о клиенте и пользователе. Затем API используют эти сведения для авторизации доступа к их данным. Сведения о настройке IdentityServer для защиты API см. в разделе "Настройка ресурсов API".

Настройка IdentityServer для выполнения авторизации

Чтобы выполнить авторизацию с помощью IdentityServer, его ПО промежуточного слоя авторизации необходимо добавить в конвейер HTTP-запроса веб-приложения. ПО промежуточного слоя добавляется в ConfigureAuth метод в классе веб-приложения Startup , который вызывается из Configure метода и демонстрируется в следующем примере кода из справочного приложения eShopOnContainers:

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

Этот метод гарантирует, что к API можно получить доступ только с допустимым маркером доступа. ПО промежуточного слоя проверяет входящие маркеры, чтобы убедиться, что он отправляется из доверенного издателя, и проверяет, является ли маркер допустимым для использования с API, который получает его. Таким образом, при просмотре в контроллер заказа или корзине возвращается код состояния HTTP 401 (несанкционированный), указывающий на необходимость маркера доступа.

Примечание.

По промежуточному слоя авторизации IdentityServer необходимо добавить в конвейер HTTP-запроса веб-приложения, прежде чем добавлять MVC с app.UseMvc() или app.UseMvcWithDefaultRoute().

Выполнение запросов доступа к API

При выполнении запросов к микрослужбам заказа и корзины маркер доступа, полученный из IdentityServer во время процесса проверки подлинности, должен быть включен в запрос, как показано в следующем примере кода:

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

Маркер доступа хранится в качестве параметра приложения и извлекается из хранилища для конкретной платформы и включается в вызов GetOrderAsync метода в OrderService классе.

Аналогичным образом маркер доступа должен быть включен при отправке данных в защищенный API IdentityServer, как показано в следующем примере кода:

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

Маркер доступа извлекается из хранилища для конкретной платформы и включается в вызов UpdateBasketAsync метода в BasketService классе.

Класс RequestProvider в мобильном приложении eShopOnContainers использует HttpClient класс для выполнения запросов к API RESTful, предоставляемым эталонным приложением eShopOnContainers. При выполнении запросов к API заказа и корзине, для которых требуется авторизация, допустимый маркер доступа должен быть включен в запрос. Это достигается путем добавления маркера доступа к заголовкам HttpClient экземпляра, как показано в следующем примере кода:

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

Свойство DefaultRequestHeadersHttpClient класса предоставляет заголовки, отправляемые с каждым запросом, и маркер доступа добавляется в Authorization заголовок, префикс с помощью строки Bearer. Когда запрос отправляется в API RESTful, значение Authorization заголовка извлекается и проверяется, чтобы убедиться, что он отправляется из доверенного издателя и используется для определения того, имеет ли пользователь разрешение на вызов API, который получает его.

Дополнительные сведения о том, как мобильное приложение eShopOnContainers выполняет веб-запросы, см. в разделе "Доступ к удаленным данным".

Итоги

Существует множество подходов к интеграции проверки подлинности и авторизации в Xamarin.Forms приложение, которое взаимодействует с веб-приложением ASP.NET MVC. Мобильное приложение eShopOnContainers выполняет проверку подлинности и авторизацию с помощью контейнерной микрослужбы удостоверений, использующего IdentityServer 4. IdentityServer — это платформа открытый код OpenID Подключение и OAuth 2.0 для ASP.NET Core, которая интегрируется с ASP.NET Core Identity для проверки подлинности маркера носителя.

Мобильное приложение запрашивает маркеры безопасности из IdentityServer либо для проверки подлинности пользователя, либо для доступа к ресурсу. При доступе к ресурсу маркер доступа должен быть включен в запрос к API, которым требуется авторизация. ПО промежуточного слоя IdentityServer проверяет входящие маркеры доступа, чтобы убедиться, что они отправляются из доверенного издателя, и что они допустимы для использования с API, который получает их.