Аутентификация и авторизация
Примечание.
Эта электронная книга была опубликована весной 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 Connect и OAuth 2.0 для ASP.NET Core, которая может использоваться для многих сценариев проверки подлинности и авторизации, включая выдачу маркеров безопасности для локальных пользователей ASP.NET Core Identity.
Примечание.
OpenID Connect и OAuth 2.0 очень похожи, хотя и имеют разные обязанности.
OpenID Connect — это уровень проверки подлинности поверх протокола OAuth 2.0. OAuth 2 — это протокол, позволяющий приложениям запрашивать маркеры доступа из службы маркеров безопасности и использовать их для взаимодействия с API. Это делегирование снижает сложность как клиентских приложений, так и API, так как проверка подлинности и авторизация могут быть централизованны.
Сочетание OpenID Connect и OAuth 2.0 объединяет две основные проблемы безопасности для проверки подлинности и доступа к API, а IdentityServer 4 — реализация этих протоколов.
В приложениях, использующих прямое взаимодействие между клиентами и микрослужбами, например эталонное приложение eShopOnContainers, выделенная микрослужба проверки подлинности, выступающая в качестве службы маркеров безопасности (STS), может использоваться для проверки подлинности пользователей, как показано на рис. 9-1. Дополнительные сведения о прямой связи между клиентами и микрослужбами см. в разделе "Обмен данными между клиентами и микрослужбами".
Рис. 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 Connect и 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 Connect указывает некоторые стандартные ресурсы удостоверений. Минимальное требование заключается в том, что поддержка предоставляется для создания уникального идентификатора для пользователей. Это достигается путем предоставления IdentityResources.OpenId
ресурса удостоверений.
Примечание.
Класс IdentityResources
поддерживает все области, определенные в спецификации OpenID Connect (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 Connect и OAuth 2.0 определяют ряд потоков проверки подлинности, в том числе:
- Подразумеваемый. Этот поток оптимизирован для приложений на основе браузера и должен использоваться только для проверки подлинности пользователей, а также для запросов маркеров доступа и проверки подлинности. Все маркеры передаются через браузер, поэтому расширенные функции, такие как маркеры обновления, не допускаются.
- Код авторизации. Этот поток обеспечивает возможность получения маркеров на заднем канале, а не внешнего канала браузера, а также поддержки проверки подлинности клиента.
- Гибридный. Этот поток представляет собой сочетание неявных и типов предоставления кода авторизации. Маркер удостоверения передается через канал браузера и содержит подписанный ответ протокола вместе с другими артефактами, такими как код авторизации. После успешной проверки ответа канал обратной части должен использоваться для получения маркера доступа и обновления.
Совет
Используйте поток гибридной проверки подлинности. Поток гибридной проверки подлинности устраняет ряд атак, которые применяются к каналу браузера, и это рекомендуемый поток для собственных приложений, которые хотят получить маркеры доступа (и, возможно, маркеры обновления).
Дополнительные сведения о потоках проверки подлинности см . в документации по IdentityServer 4.
Выполнение проверки подлинности
Чтобы IdentityServer выдавал маркеры от имени пользователя, пользователь должен войти в IdentityServer. Однако IdentityServer не предоставляет пользовательский интерфейс или базу данных для проверки подлинности. Поэтому в справочном приложении eShopOnContainers ASP.NET Core Identity используется для этой цели.
Мобильное приложение eShopOnContainers проходит проверку подлинности с помощью IdentityServer с помощью потока гибридной проверки подлинности, который показан на рис. 9-2.
Рис. 9-2. Общие сведения о процессе входа
Запрос на вход выполняется <base endpoint>:5105/connect/authorize
. После успешной проверки подлинности IdentityServer возвращает ответ проверки подлинности, содержащий код авторизации и маркер удостоверения. Затем код авторизации отправляется <base endpoint>:5105/connect/token
в , в который отвечает маркеры доступа, удостоверения и обновления.
Мобильное приложение eShopOnContainers выходит из IdentityServer, отправляя запрос <base endpoint>:5105/connect/endsession
на использование дополнительных параметров. После выхода IdentityServer отвечает, отправив URI перенаправления после выхода обратно в мобильное приложение. Рис. 9-3 иллюстрирует этот процесс.
Рис. 9-3. Общие сведения о процессе выхода
В мобильном приложении eShopOnContainers обмен данными с IdentityServer выполняется классом IdentityService
, который реализует IIdentityService
интерфейс. Этот интерфейс указывает, что реализующий класс должен предоставлять CreateAuthorizationRequest
и CreateLogoutRequest
GetTokenAsync
методы.
Вход
Когда пользователь нажимает кнопку 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.
Рис. 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
классе, LogoutCommand
ProfileViewModel
который, в свою очередь, выполняет 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
, которое приводит к тому, что на WebView
LoginView
странице становится невидимым. Наконец, LoginUrl
для свойства задан универсальный код ресурса (URI) конечной точки авторизации IdentityServer с необходимыми параметрами при подготовке к следующему запуску входа.
Сведения о навигации по страницам см. в разделе "Навигация". Сведения о том, как WebView
навигация приводит к выполнению метода модели представления, см. в статье "Вызов навигации с помощью поведения". Сведения о параметрах приложения см. в разделе "Управление конфигурацией".
Примечание.
EShopOnContainers также позволяет выходить из системы, когда приложение настроено на использование макетных служб в SettingsView. В этом режиме приложение не взаимодействует с 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.
Рис. 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);
Свойство DefaultRequestHeaders
HttpClient
класса предоставляет заголовки, отправляемые с каждым запросом, и маркер доступа добавляется в Authorization
заголовок, префикс с помощью строки Bearer
. Когда запрос отправляется в API RESTful, значение Authorization
заголовка извлекается и проверяется, чтобы убедиться, что он отправляется из доверенного издателя и используется для определения того, имеет ли пользователь разрешение на вызов API, который получает его.
Дополнительные сведения о том, как мобильное приложение eShopOnContainers выполняет веб-запросы, см. в разделе "Доступ к удаленным данным".
Итоги
Существует множество подходов к интеграции проверки подлинности и авторизации в Xamarin.Forms приложение, которое взаимодействует с веб-приложением ASP.NET MVC. Мобильное приложение eShopOnContainers выполняет проверку подлинности и авторизацию с помощью контейнерной микрослужбы удостоверений, использующего IdentityServer 4. IdentityServer — это платформа открытый код OpenID Connect и OAuth 2.0 для ASP.NET Core, которая интегрируется с ASP.NET Core Identity для выполнения проверки подлинности маркера носителя.
Мобильное приложение запрашивает маркеры безопасности из IdentityServer либо для проверки подлинности пользователя, либо для доступа к ресурсу. При доступе к ресурсу маркер доступа должен быть включен в запрос к API, которым требуется авторизация. ПО промежуточного слоя IdentityServer проверяет входящие маркеры доступа, чтобы убедиться, что они отправляются из доверенного издателя, и что они допустимы для использования с API, который получает их.