Назад | Перейти на главную страницу

OAUTH / OIDC - аутентификация клиента с использованием подписанного JWT вместо секретного

Я отправляю сигнальную ракету после того, как исчерпал свои поисковые усилия. Я чувствую, что очень близок к тому, чтобы это заработало, но упираюсь в стену. Ниже приводится подробный пример того, чего я пытаюсь достичь, и предпринятых шагов. Укажите на ошибки и внесите предложения, если возможно.


У меня есть приложение OAUTH / OPENID / OIDC, зарегистрированное в Azure, и я хочу использовать сертификат для аутентификации моего клиента вместо секрета клиента.


Я сгенерировал сертификат, экспортировал и загрузил общедоступную часть в раздел конфигурации «сертификаты и секреты». Отпечаток: 3BC87980310C490A62AA5F6343D4C55DF8EBBA85

Манифест с измененными значениями ...

«keyCredentials»: [{«customKeyIdentifier»: «3BC87980310C490A62AA5F6343D4C55DF8EBBA85», «endDate»: «2020-10-10T19: 45: 00Z», «keyId»: «ff3ce8e8-7268-4b395-88ea-dd «2019-10-10T19: 45: 00Z», «type»: «AsymmetricX509Cert», «usage»: «Verify», «value»: «LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0 ....», «displayName»: «L = mycity, E =myemail@email.com, CN = jarred-test-oauth, OU = Federation, O = 12345 "


Аутентификация достаточно проста и могу получить код авторизации. Я подписал свое клиентское утверждение JWT с помощью частного сертификата:

Заголовок: {"alg": "RS256", "typ": "JWT"}

Полезная нагрузка: {"iss": "2f877daa-b6f5-42a3-8430-acf238b234e1", "sub": "2f877daa-b6f5-42a3-8430-acf238b234e1", "nbf": 1570803651, "exp": 1570807251 : 1570803651, "jti": "3BC87980310C490A62AA5F6343D4C55DF8EBBA85", "typ": "JWT"}

"iss" и "sub" - это client_id моего приложения в Azure.


Я попытался протестировать обмен кода на токены со следующим в Postman:

ПОЧТА: https://login.microsoftonline.com/my-tenant/oauth2/v2.0/token

Заголовки: Content-Type = application / x-www-form-urlencoded

Тело: grant_type = authorization_code

код = полученный_код

client_assertion_type = urn: ietf: params: oauth: client-assertion-type: jwt-bearer

client_assertion = eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIyZjg3N2RhYS1iNmY1LTQyYTMtODQzMC1hY2YyMzhiMjM0ZTEiLCJzdWIiOiIyZjg3N2RhYS1iNmY1LTQyYTMtODQzMC1hY2YyMzhiMjM0ZTEiLCJuYmYiOjE1NzA4MDM2NTEsImV4cCI6MTU3MDgwNzI1MSwiaWF0IjoxNTcwODAzNjUxLCJqdGkiOiIzQkM4Nzk4MDMxMEM0OTBBNjJBQTVGNjM0M0Q0QzU1REY4RUJCQTg1IiwidHlwIjoiSldUIn0.t8lArFodXkHO9Ps9O3q7VH55pRl6NtcIkEbSz-hDL0V6I7iWi4N-1VBNM_nFUHkNhBoGaskV0eQtqMXYildb7oEr75KgbcjacZy2OI319uPwztHp9jVxjsBhB_rKXND4M6URr23IWkLwFb2008vq_fY4trLUZR9ILZOE0Dr_MdaQmrt8fU9mYNkSEnRsiXKuqcS97oBfo6-9MuDbkcNuAOxZnsmbYvutk1LeabFywbc4qO3dgb8PtfqMAiYxgYTzg72tAw-ncq6uRXgG5XoxJVOExCyn5CXV9lSsE33_oekOEfRU5CyC0IvtSLhSoZ7LKtSMJ22ZXiyFqvddenJC8w


Отправка запроса приводит к следующей ошибке от Azure (в почтальоне):

{"error": "invalid_request", "error_description": "AADSTS5002723: Недействительный токен JWT. В заголовке токена не указаны ни отпечаток сертификата, ни идентификатор ключа. \ r \ nИдентификатор трассы: 89f69560-9ae7-482f-803c-9faa71d44100 \ r \ nИдентификатор корреляции : e2ebab72-8b4d-47a6-85be-14893158dd5e \ r \ nTimestamp: 2019-10-11 14: 23: 32Z "," error_codes ": [5002723]," timestamp ":" 2019-10-11 14: 23: 32Z "," trace_id ":" 89f69560-9ae7-482f-803c-9faa71d44100 "," correlation_id ":" e2ebab72-8b4d-47a6-85be-14893158dd5e "}

Я предполагаю, что заголовок должен содержать значение KID или «отпечаток пальца». У меня нет KID, поскольку я не настраиваю для этой цели общедоступный JWKS и не уверен, что вводить в качестве поля для отпечатка пальца.


Очень признателен, если кто-то может указать мне правильное направление. Я уже видел все ссылки на других, которые задавали вопросы. Я действительно мог бы попросить кого-нибудь, кто знает, что делать дальше.


Вот несколько инструментов и документов, которые помогли мне продвинуться так далеко:

Инструмент подписи JWT - http://kjur.github.io/jsjws/tool_jwt.html

Объяснение аутентификации клиента Oauth - https://medium.com/@darutk/oauth-2-0-client-authentication-4b5f929305d4

RFC 7523 Профили утверждений OAuth JWT - https://tools.ietf.org/html/rfc7523#section-2.2

Блог Microsoft - https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client- учетные данные /

Веб-токен JSON (JWT) - Заявления и подпись draft-jones-json-web-token-01 - https://tools.ietf.org/id/draft-jones-json-web-token-01.html

КБ для аутентификации клиента - https://kb.authlete.com/en/s/oauth-and-openid-connect/a/client-secret-jwt

Спасибо!

- Jarred

Пришлось запаниковать, прежде чем найти ответ. 5 дней поиска и вот мои выводы на тот случай, если кто-то еще найдет этот вопрос и ему понадобится помощь.

Быстрые шаги:

  1. Создайте свой закрытый ключ (ниже используется PowerShell)

  2. Создайте свой публичный сертификат

  3. Преобразуйте публичный сертификат и закрытый ключ в формат PEM

  4. Загрузите публичный сертификат в конфигурацию приложения в разделе «Сертификаты и секреты».

  5. Получите отпечаток вашего сертификата в Base64 (либо возьмите при создании сертификата, либо найдите в хранилище ключей или другом месте)

$cert=New-SelfSignedCertificate -Subject "CN=$ApplicationName" -CertStoreLocation "Cert:\CurrentUser\My"  -NotAfter (Get-Date).AddMonths(24) -KeyExportPolicy Exportable -KeySpec Signature
$bin = $cert.RawData
$base64Value = [System.Convert]::ToBase64String($bin)
$bin = $cert.GetCertHash()
$base64Thumbprint = [System.Convert]::ToBase64String($bin)
  1. создайте свой JWT (я использовал https://jwt.io/)

Заголовок

{
  "alg": "RS256",
  "typ": "JWT",
  "x5t": "<Base64 Thumbprint>"
}

Полезная нагрузка

{
  "iss": "<clientid>",
  "sub": "<clientid>",
  "exp": 1570838377 (expiration time),
  "jti": "<random unique identifier>",
  "aud": "https://<token-endpoint>"
}

Поместите свой закрытый ключ (PEM) в нижний верификатор, который подпишет ваш JWT в окне «Закодировано».

  1. Получите код авторизации
  2. Составьте свой запрос на токены

Заголовок

Content-Type: application/x-www-form-urlencoded

Тело

grant_type=authorization_code
code=OAQABAAIAAACQN9QBR.... (your authorization code)
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
client_assertion=eyJhbGciOiJSUzI1NiIsInR5.... (your signed JWT)
state=state (optional)
redirect_uri=https%3A%2F%2Fblackhole.com (The callback URI)
  1. POST на конечную точку вашего токена. Если все пойдет по плану, вы должны получить свои жетоны.