Практическое руководство. Запрос маркера из ACS с помощью протокола OAuth WRAP
Применяется к
- Microsoft Azure Active Directory Access Control (также называется Access Control Service или ACS)
Обзор
Когда веб-приложения и службы обрабатывают проверку подлинности с помощью ACS, клиент должен получить маркер безопасности, выданный ACS для входа в приложение или службу. Чтобы получить маркер, выданный ACS (выходной маркер), клиент должен либо пройти проверку подлинности напрямую с помощью ACS, либо отправить ACS маркер безопасности, выданный поставщиком удостоверений (входным маркером). ACS проверяет этот входной маркер безопасности, обрабатывает утверждения удостоверений в этом маркере с помощью обработчика правил ACS, вычисляет утверждения выходных удостоверений и выдает выходной маркер безопасности.
В этом разделе описываются методы запроса маркера из ACS через протокол OAuth WRAP. Все запросы маркеров через протокол OAuth WRAP передаются по протоколу SSL. ACS всегда выдает простой веб-токен (SWT) через протокол OAuth WRAP в ответ на правильно отформатированный запрос маркера. Все запросы маркеров через протокол OAuth WRAP отправляются в ACS в HTTP POST. Маркер ACS можно запросить с помощью протокола OAuth WRAP с любой платформы, которая может создать HTTPS FORM POST: платформа .NET Framework, Windows Communication Foundation (WCF), Silverlight, ASP.NET, Java, Python, Ruby, PHP, Flash и другие платформы.
В следующей таблице перечислены три поддерживаемых метода запроса токена SWT, выданного ACS, через протокол OAuth WRAP.
Три метода запроса маркера из ACS по протоколу OAuth WRAP
Метод запроса маркера | Описание |
---|---|
Запросы маркеров паролей |
Этот самый простой метод требует, чтобы клиент отправлял имя пользователя и пароль из удостоверения службы непосредственно в ACS через протокол OAuth WRAP для проверки подлинности. |
Запросы маркеров SWT |
Этот метод требует, чтобы клиент отправлял маркер SWT, который может быть подписан симметричным ключом удостоверения службы или симметричным ключом поставщика удостоверений в ACS через протокол OAuth WRAP для проверки подлинности. |
Запросы маркеров SAML |
В первую очередь для интеграции службы федерации Active Directory (AD FS) 2.0 метод saml требует, чтобы клиент отправлял подписанный токен SAML в ACS через протокол OAuth WRAP для проверки подлинности. Такой подход позволяет клиенту использовать корпоративное удостоверение для проверки подлинности с помощью ACS. |
Конечная точка издания маркера
Все запросы маркера ACS через протокол OAuth WRAP направляются в конечную точку, выдаваемую маркерами ACS. Универсальный код ресурса (URI) этой конечной точки зависит от пространства имен контроль доступа. Пространство имен появляется в виде префикса имени DNS в URI запроса маркера. Остальная часть имени DNS фиксирована, как и путь. Например, если вы хотите запросить маркер из пространства имен контроль доступа с именем mysnservice, можно направить запрос маркера к следующему URI: https://mysnservice.accesscontrol.windows.net/WRAPv0.9
Запросы маркеров паролей
С помощью запроса маркера пароля клиент может отправить имя пользователя и пароль из удостоверения службы непосредственно в ACS через протокол OAuth WRAP для проверки подлинности. Это самый простой способ запросить маркер из ACS с помощью протокола OAuth WRAP. Кроме установки соединения SSL, этот подход не требует наличия возможности шифрования. На практике это похоже на модель «имя пользователя и пароль», которая широко распространена в веб-службах REST. Этот тип запроса маркера фактически представляет собой формы HTTPS POST. Параметры запроса маркера пароля, зашифрованные в форме.
Ниже приведен пример трассировки сети открытым текстом запроса в пространство имен с именем «mysnservice».
POST /WRAPv0.9/ HTTP/1.1
Host: mysnservice.accesscontrol.windows.net
Content-Type: application/x-www-form-urlencoded
wrap_scope=http%3A%2F%2Fmysnservice.com%2Fservices%2F&
wrap_name=mysncustomer1&
wrap_password=5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ%3D
В таблице ниже приведены имена, описания и требования к значениям параметров, которые должны присутствовать в запросе маркера пароля.
Имя параметра | Описание | Требования к значениям |
---|---|---|
wrap_scope |
Сопоставляет запрос маркера с набором правил. Задайте значение этого параметра, равным значению области приложения проверяющей стороны. Это значение (в поле области ) можно получить на портале управления ACS, выбрав соответствующее приложение проверяющей стороны на странице "Приложения проверяющей стороны ". |
|
wrap_name |
Проверяет ключ следующего параметра. Задайте для этого параметра имя удостоверения службы в пространстве имен контроль доступа. Это значение (в поле "Имя ") можно получить на портале управления ACS, выбрав соответствующее удостоверение службы на странице удостоверений службы . |
|
wrap_password |
Выполняет проверку подлинности входящего запроса. Задайте для этого параметра пароль удостоверения службы в пространстве имен контроль доступа. Это значение (в поле "Пароль " на странице "Изменение учетных данных ") можно получить на портале управления ACS, выбрав соответствующее удостоверение службы на странице " Удостоверения службы ", а затем выбрав соответствующий пароль в таблице "Учетные данные " на странице "Изменение удостоверения службы ". |
|
Значения этих параметров должны быть закодированы по URL-адресу перед отправкой запроса в ACS. Веб-приложение или служба могут предоставить клиенту значение wrap_scope , или клиент может задать значение параметра wrap_scope URI веб-приложения или целевого ресурса службы.
Запросы маркера пароля через протокол OAuth WRAP также могут содержать дополнительные параметры, которые ACS могут использовать во время вычисления исходящих утверждений. Эти имена и значения дополнительных параметров должны быть закодированы как URL-адреса, значения не должны быть заключены в кавычки.
Метод запроса маркера пароля с использованием довольно прост.
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");
// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);
// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);
Сведения о том, как распаковывать выходной маркер из ACS и отправлять его в веб-приложение или службу, см. в разделе "Распаковка и отправка маркера в веб-приложение или службу".
Запросы маркеров SWT
Вы также можете запросить маркер из ACS через протокол OAuth WRAP с помощью токена SWT, подписанного симметричным ключом. Все запросы маркеров SWT выполняются через формы HTTPS POST. Значения параметров в этом методе запроса маркера зашифрованы в форме.
Ниже приведен пример трассировки сети запроса маркера SWT пространству имен «mysnservice».
POST /WRAPv0.9/ HTTP/1.1
Host: mysnservice.accesscontrol.windows.net
Content-Type: application/x-www-form-urlencoded
wrap_scope=http%3A%2F%2Fmysnservice.com%2Fservices%2F&
wrap_assertion_format=SWT&
wrap_assertion=Issuer%3dmysncustomer1%26HMACSHA256%3db%252f%252bJFwbngGdufECFjQb8qhb9YH0e32Cf9ABMDZFiPPA%253d
Запрос маркера SWT должен иметь следующие параметры и значения.
Имя параметра | Описание | Требования к значениям |
---|---|---|
wrap_scope |
Сопоставляет запрос маркера с набором правил. |
|
wrap_assertion |
Это входной маркер, который отправляется в ACS. |
|
wrap_assertion_format |
Это формат входного маркера, который отправляется в ACS. |
SWT |
Как показано в следующем примере, код, необходимый для создания запроса маркера SWT, напоминает код, который требуется для запроса маркера пароля.
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
NameValueCollection values = new NameValueCollection();
// add the wrap_scope
values.Add("wrap_scope", "http://mysnservice.com/services");
// add the format
values.Add("wrap_assertion_format", "SWT");
// add the SWT
values.Add("wrap_assertion", "Issuer=mysncustomer1&HMACSHA256=b%2f%2bJFwbngGdufECFjQb8qhb9YH0e32Cf9ABMDZFiPPA%3d");
// WebClient takes care of the remaining URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);
// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);
Сведения о том, как распаковывать ответ от ACS и отправлять его в веб-приложение или службу, см. в разделе "Распаковка" и отправка маркера в веб-приложение или службу.
Создание маркера SWT
Маркер SWT — это набор пар «ключ-значение», подписанных с помощью ключа издателя (симметричного ключа). Маркер SWT, отправленный в ACS в запросе маркера SWT, должен содержать параметры издателя и HMACSHA256 , а также дополнительные параметры, например ExpiresOn, Audience и другие утверждения, относящиеся к клиенту. В следующей таблице приведены имена и описания параметров маркера SWT.
Имя параметра | Описание |
---|---|
Издатель |
В ACS найдите ключ, который использовался для подписи маркера. Если подпись является допустимой, это значение используется для выполнения вычисления исходящего утверждения. Этот параметр можно задать в качестве значения области поставщика удостоверений в пространстве имен контроль доступа или имени удостоверения службы в пространстве имен контроль доступа. Это значение можно получить (в поле "Область " на странице "Изменение поставщика удостоверений ") на портале управления ACS, выбрав соответствующего поставщика удостоверений на странице "Поставщики удостоверений". Или вы можете получить это значение с помощью службы управления ACS. Это свойство имени записи issuer, созданной для каждого поставщика удостоверений. |
HMACSHA256 |
В ACS проверяет сигнатуру SWT и ищет ключ издателя, названный в параметре Issuer . Подпись SWT создается с помощью симметричного ключа подписи, присоединенного к удостоверению службы или поставщику удостоверений в контроль доступа пространстве имен. |
Аудитория |
При наличии ACS использует это значение, чтобы убедиться, что ACS является целевым объектом маркера SWT. Это URL-адрес пространства имен контроль доступа, напримерhttps://contoso.accesscontrol.windows.net/ |
Срок действия истекает |
Если имеется (во время эпохи), указывает, истек ли срок действия маркера. Например, значение этого параметра может быть |
Дополнительные утверждения |
В этом случае ACS использует эти параметры для вычисления выходных утверждений. Каждый тип утверждения должен появляться только один раз. Несколько значений утверждения того же типа утверждения должны быть объединены с помощью символа «,» (запятая). Дополнительные сведения об утверждении утверждений в ACS см. в описании утверждения утверждений через протокол OAuth WRAP. |
В следующем примере кода показано, как создать маркер SWT с помощью . Он содержит тип, который создает маркеры SWT, содержащие параметры издателя и HMACSHA256.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
public class TokenFactory
{
string signingKey;
string issuer;
public TokenFactory(string issuer, string signingKey)
{
this.issuer = issuer;
this.signingKey = signingKey;
}
public string CreateToken()
{
StringBuilder builder = new StringBuilder();
// add the issuer name
builder.Append("Issuer=");
builder.Append(HttpUtility.UrlEncode(this.issuer));
string signature = this.GenerateSignature(builder.ToString(), this.signingKey);
builder.Append("&HMACSHA256=");
builder.Append(signature);
return builder.ToString();
}
private string GenerateSignature(string unsignedToken, string signingKey)
{
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(signingKey));
byte[] locallyGeneratedSignatureInBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));
string locallyGeneratedSignature = HttpUtility.UrlEncode(Convert.ToBase64String(locallyGeneratedSignatureInBytes));
return locallyGeneratedSignature;
}
}
Запросы маркеров SAML
Метод запроса токена SAML предназначен главным образом для интеграции AD FS 2.0 и позволяет клиенту использовать корпоративное удостоверение (Active Directory) для проверки подлинности с помощью ACS. С помощью метода запроса токена SAML можно отправить подписанный токен SAML 1.1 или токен SAML 2.0, выданный AD FS 2.0 (входной маркер) в ACS с помощью протокола OAuth WRAP.
ACS использует его правила для вычисления исходящих утверждений, группирует их в маркер SWT (исходящий маркер), подписывает его и возвращает клиенту по протоколу OAuth WRAP.
Запрос маркера SWT должен иметь следующие параметры и значения.
Имя параметра | Описание | Требования к значениям |
---|---|---|
wrap_scope |
Сопоставляет запрос маркера с набором правил. |
|
wrap_assertion |
Это входной маркер, отправляемый в ACS. |
|
wrap_assertion_format |
Это формат входного токена, отправляемого в ACS. |
SAML |
Ниже приведен пример кода, который необходим, чтобы сделать запрос маркера SAML.
private static string SendSAMLTokenToACS(string samlToken)
{
try
{
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
NameValueCollection parameters = new NameValueCollection();
parameters.Add("wrap_assertion_format", "SAML");
parameters.Add("wrap_assertion", samlToken);
parameters.Add("wrap_scope", "http://mysnservice.com/services");
byte[] responseBytes = client.UploadValues("WRAPv0.9", parameters);
string response = Encoding.UTF8.GetString(responseBytes);
return response
.Split('&')
.Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
.Split('=')[1];
}
catch (WebException wex)
{
string value = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
throw;
}
}
Сведения о том, как распаковывать ответ от ACS и отправлять его в веб-приложение или службу, см. в разделе "Распаковка" и отправка маркера в веб-приложение или службу.
Подтверждение утверждений по протоколу OAuth WRAP
Чтобы обеспечить обратную совместимость с поведением запроса маркера ACS 1.0, ACS поддерживает возможность утверждения утверждений в рамках запросов маркеров.
Зарегистрируйте приложение подтверждения или службу как поставщика удостоверений ACS.
Для этого рекомендуется зарегистрировать в качестве поставщика удостоверений ACS приложение или службу подтверждения. Затем приложение или служба запрашивает маркер из ACS, предоставляя токен SAML или SWT, содержащий утверждения, которые требуется подтвердить, и этот маркер подписывается с помощью ключа поставщика удостоверений, хранящегося в ACS. Например, можно отправить запрос токена SAML с утверждениями в ACS с помощью протокола OAuth WRAP из AD FS 2.0 или любой пользовательской службы маркеров безопасности (STS), созданной с помощью Windows Identity Foundation (WIF) и зарегистрированного в ACS в качестве поставщика удостоверений WS-Federation.
Портал управления ACS можно использовать для регистрации поставщика удостоверений с помощью WS-Federation метаданных или для настройки свойств поставщика удостоверений, адресов и ключей с помощью службы управления ACS. (Например, см. инструкции. Использование службы управления ACS для настройки AD FS 2.0 в качестве поставщика удостоверений Enterprise.) В этом методе подтверждения утверждений в запросе маркера удостоверения службы не требуются. Этот метод работает через все протоколы, поддерживаемые ACS.
Распаковывание и отправка маркера для веб-приложения или службы
Если запрос маркера успешно прошел проверку подлинности, ACS возвращает два параметра в кодировке формы: wrap_token и wrap_token_expires_in. Значения этих параметров фактически представляют собой маркер SWT, который клиент может использовать для получения доступа к веб-приложению или службе, и приблизительное оставшееся время существования маркера (в секундах) соответственно.
Перед отправкой маркера SWT в веб-приложение или службу клиент должен извлечь и декодировать его из ответа ACS. Если веб-приложение или служба требует представления маркера в заголовке HTTP Authorization
, этому маркеру должна предшествовать схема WRAPv0.9
.
В следующем примере кода показано, как распаковать маркер и формат заголовка Authorization
.
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");
// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);
// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);
string token = response
.Split('&')
.Single(value => value.StartsWith("wrap_token=", StringComparison.OrdinalIgnoreCase))
.Split('=')[1];
string.Format("WRAP access_token=\"{0}\"", HttpUtility.UrlDecode(token));
Коды ошибок ACS и описания
ACS возвращает ошибки, когда не удается удовлетворить запрос маркера. В соответствии с разработкой REST ошибка содержит код ответа HTTP. Во многих случаях ошибки ACS также содержат контекст SubCode
Detail
о том, что завершилось сбоем. Формат ошибки: Error:Code:httpStatus:<Sub-Code:<code>:D etail:<message>>.
Content-Type
ошибки всегда «text/plain».
HTTP/1.1 401 Access Forbidden
Content-Type: text/plain; charset=us-ascii
Error:Code:401:SubCode:T0:Detail:ACS50009: SWT token is invalid. :TraceID:<trace id value>:TimeStamp:<timestamp value>
Дополнительные сведения о кодах ошибок ACS см. в разделе "Коды ошибок ACS".
При отладке или восстановлении после ошибки, возвращаемой из ACS, часто требуется считывать текст ответа. В следующем примере кода показано, как считывать сообщение об ошибке из объекта WebException .
try
{
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");
// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);
// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);
string token = response
.Split('&')
.Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
.Split('=')[1];
}
catch (WebException wex)
{
if (wex.Response != null)
{
// the response Stream contains the error message
StreamReader reader = new StreamReader(wex.Response.GetResponseStream());
string message = reader.ReadToEnd();
}
// Throw as appropriate
}