Я отправляю сигнальную ракету после того, как исчерпал свои поисковые усилия. Я чувствую, что очень близок к тому, чтобы это заработало, но упираюсь в стену. Ниже приводится подробный пример того, чего я пытаюсь достичь, и предпринятых шагов. Укажите на ошибки и внесите предложения, если возможно.
У меня есть приложение 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
Веб-токен 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 дней поиска и вот мои выводы на тот случай, если кто-то еще найдет этот вопрос и ему понадобится помощь.
Быстрые шаги:
Создайте свой закрытый ключ (ниже используется PowerShell)
Создайте свой публичный сертификат
Преобразуйте публичный сертификат и закрытый ключ в формат PEM
Загрузите публичный сертификат в конфигурацию приложения в разделе «Сертификаты и секреты».
Получите отпечаток вашего сертификата в 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)
Заголовок
{
"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 в окне «Закодировано».
Заголовок
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)