在我耗尽搜索精力后,我发出了信号弹。我感觉我离成功只有一步之遥,但却遇到了瓶颈。下面详细介绍了我试图完成的任务以及迄今为止采取的步骤。请指出错误并提出建议。
我有一个在 Azure 中注册的 OAUTH/OPENID/OIDC 应用程序,并且想要使用证书而不是客户端机密来验证我的客户端。
我生成了一个证书,导出并将公共部分上传到配置的“证书和机密”部分。指纹:3BC87980310C490A62AA5F6343D4C55DF8EBBA85
清单中的值已修改...
“keyCredentials”:[{“customKeyIdentifier”:“3BC87980310C490A62AA5F6343D4C55DF8EBBA85”,“endDate”:“2020-10-10T19:45:00Z”,“keyId”:“ff3ce8e8-7268-4b46-88be-d3a191a0695e”,“startDate”:“2019-10-10T19:45:00Z”,“type”:“AsymmetricX509Cert”,“usage”:“验证”,“value”:“LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0....”,“displayName”:“L = mycity,[电子邮件保护], CN = jarred-test-oauth, OU = 联合, O = 12345”
身份验证非常简单,我能够获得授权码。我使用私有证书签署了客户端断言 JWT:
标题:{“alg”:“RS256”,“typ”:“JWT”}
有效负载:{“iss”:“2f877daa-b6f5-42a3-8430-acf238b234e1”,“sub”:“2f877daa-b6f5-42a3-8430-acf238b234e1”,“nbf”:1570803651,“exp”:1570807251,“iat”:1570803651,“jti”:“3BC87980310C490A62AA5F6343D4C55DF8EBBA85”,“typ”:“JWT”}
“iss”和“sub”是我的应用程序在Azure中的client_id。
我尝试在 Postman 中使用以下命令测试代码与令牌的交换:
邮政:https://login.microsoftonline.com/my-tenant/oauth2/v2.0/token
标头:Content-Type = application/x-www-form-urlencoded
正文:grant_type = authorization_code
code = 获得的代码
客户端断言类型 = urn:ietf:params:oauth:客户端断言类型:jwt-bearer
客户端断言 = eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIyZjg3N2RhYS1iNmY1LTQyYTMtODQzMC1hY2YyMzhiMjM0ZTEiLCJzdWIiOiIyZjg3N2RhYS1iNmY1LTQyYTMtODQzMC1hY2YyMzhiMjM0ZTEiLCJuY mYiOjE1NzA4MDM2NTEsImV4cCI6MTU3MDgwNzI1MSwiaWF0IjoxNTcwODAzNjUxLCJqdGkiOiIzQkM4Nzk4MDMxMEM0OTBBNjJBQTVGNjM0M0Q0QzU1REY4RUJCQTg1IiwidHlwIjoiSldUIn0.t8lArFodXkHO9Ps9 O3q7VH55pRl6NtcIkEbSz-hDL0V6I7iWi4N-1VBNM_nFUHkNhBoGaskV0eQtqMXYildb7oEr75KgbcjacZy2OI319uPwztHp9jVxjsBhB_rKXND4M6URr23IWkLwFb2008vq_fY4trLUZR9ILZOE0Dr_MdaQmrt8fU9 mYNkSEnRsiXKuqcS97oBfo6-9MuDbkcNuAOxZnsmbYvutk1LeabFywbc4qO3dgb8PtfqMAiYxgYTzg72tAw-ncq6uRXgG5XoxJVOExCyn5CXV9lSsE33_oekOEfRU5CyC0IvtSLhSoZ7LKtSMJ22ZXiyFqvddenJC8w
发送请求会导致 Azure(在 Postman 中)出现以下错误:
{ “error”:“invalid_request”, “error_description”:“AADSTS5002723:无效的 JWT 令牌。令牌标头中未指定证书指纹或 keyId。\r\n跟踪 ID:89f69560-9ae7-482f-803c-9faa71d44100\r\n关联 ID:e2ebab72-8b4d-47a6-85be-14893158dd5e\r\n时间戳:2019-10-11 14:23:32Z”, “error_codes”:[5002723],“timestamp”:“2019-10-11 14:23:32Z”, “trace_id”:“89f69560-9ae7-482f-803c-9faa71d44100”, “关联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://www.rfc-editor.org/rfc/rfc7523#section-2.2
JSON Web Token (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
谢谢你!
——贾里德
答案1
在找到答案之前不得不感到恐慌。经过 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)
- 构建你的 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 进行签名。
- 获取您的授权码
- 制定你的代币请求
标头
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)
- POST 到您的令牌端点。如果一切按计划进行,您应该会收到您的令牌。