Обмен токенами кода авторизации Azure AD OAuth 2.0 с использованием сертификата - PullRequest
1 голос
/ 31 мая 2019

Документы для обмена кодом авторизации OAuth2 на токены показывают, что запрос выполняется с помощью client_id и client_secret. Однако есть ли способ сделать это с помощью аутентификации на основе сертификата для приложения Azure?

1 Ответ

3 голосов
/ 31 мая 2019

Да, вы можете приобретать токены, используя сертификат, а не секрет клиента. Он покрывается как часть предоставления клиентских учетных данных.

Конечная точка Azure AD V1

Вот подробный пример кода. Он использует самозаверяющий сертификат и использует конечную точку Azure AD V1

Аутентификация в Azure AD в приложениях демона с сертификатами

certCred = new ClientAssertionCertificate(clientId, cert);
result = await authContext.AcquireTokenAsync(todoListResourceId, certCred);

В случае, если вы хотите совершать прямые вызовы на основе REST (без использования библиотеки ADAL), вот пример. Вы можете прочитать более подробную информацию о каждом из параметров здесь в Microsoft Docs:

Запрос токена доступа с сертификатом

POST /<tenant_id>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

resource=https%3A%2F%contoso.onmicrosoft.com%2Ffc7664b4-cdd6-43e1-9365-c2e1c4e1b3bf&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg&grant_type=client_credentials

конечная точка Azure AD V2

Используя библиотеку MSAL.NET, вы можете сделать это следующим образом. Здесь показаны как секрет клиента, так и варианты сертификата. (Сертификат распространяется в другом случае)

Более подробная информация доступна здесь - Потоки учетных данных клиента в MSAL.NET

// Even if this is a console application here, a daemon application is a confidential client application
IConfidentialClientApplication app;

#if !VariationWithCertificateCredentials
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
           .WithTenantId("{tenantID}")
           .WithClientSecret(config.ClientSecret)
           .Build();
#else
// Building the client credentials from a certificate
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
    .WithTenantId("{tenantID}")
    .WithCertificate(certificate)
    .Build();
#endif

// With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the
// application permissions need to be set statically (in the portal or by PowerShell), and then granted by
// a tenant administrator
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };

AuthenticationResult result = null;
try
{
 result = await app.AcquireTokenForClient(scopes)
                   .ExecuteAsync();
}
catch(MsalServiceException ex)
{
 // Case when ex.Message contains:
 // AADSTS70011 Invalid scope. The scope has to be of the form "https://resourceUrl/.default"
 // Mitigation: change the scope to be as expected
}

Опять же, в случае, если вы заинтересованы в выполнении прямых REST-вызовов (без использования библиотеки MSAL), вот пример. Более подробную информацию о каждом из параметров можно найти здесь, в Документах Microsoft:

Запрос токена доступа с сертификатом

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
...