从 Office 365 返回的 OAuth2 令牌不包含 preffered_username 声明
OAuth2 token returned from Office 365 doesn't contain a preffered_username claim
我按照 this tutorial 进行了解码,并提取了电子邮件地址(应该存储在 preferred_username属性),即如下代码:
decoded_token = Base64.urlsafe_decode64(encoded_token)
jwt = JSON.parse(decoded_token)
email = jwt['preferred_username']
问题是返回的对象不包含这个属性,我得到的类似下面:
{
"ver":"2.0",
"iss":"https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0",
"aud":"0ab6433e-84fc-469b-8c72-41f7a0241a61",
"exp":1458142389,
"iat":1458055989,
"at_hash":"0OYaLKpTTdHNBrQNOqwQ0Q",
"sub":"AAAAAAAAAAAAAAAAAAAAAC1TrOaOmvInYrFAyrQjlFI",
"tid":"9188040d-6c67-4c5b-b112-36a304b66dad"
}
快速浏览 the spec 表明我正在从 Office 365 取回正确的对象,因为 preferred_username 被提及为潜在的声明,但是它不在我取回的对象中。
可能我没有使用正确的参数调用 get_token 函数,但是 the documentation for the library is pretty sparse,所以我真的不能说。
I have raised an issue on Github.
这是Office 365端的错误,教程的错误,还是我自己做错了?
我尝试使用普通 HTTP 请求重现此问题,但我可以成功获得 preferred_username 属性。
据我所知,只有当我们在请求中指定openid范围时,我们才能得到这个属性。为了缩小这个问题的范围,我建议您尝试在没有 Ruby.
的情况下使用 Fiddler 或 Postman
下面是使用浏览器和Fiddler获取id token的测试,供大家参考:
- 使用Office 365账号在门户中注册应用(可参考教程)
- 通过下面的 link 在网络浏览器中获取授权码:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={ClientID}&response_type=code&redirect_uri={RedirectURL}&response_mode=query&scope=https%3A%2F%2Foutlook.office.com%2Fmail.read%20https%3A%2F%2Foutlook.office.com%2Fmail.send%20openid&state=12345
替换预览请求中的授权码并使用 Fiddler 来 post 获取令牌的请求:
POST: https://login.microsoftonline.com/common/oauth2/v2.0/token
grant_type=authorization_code&client_id={ClientID}&scope=https%3A%2F%2Foutlook.office.com%2Fmail.read%20https%3A%2F%2Foutlook.office.com%2Fmail.send%20openid&redirect_uri=http%3A%2F%2Flocalhost%3A55065%2F&client_secret={ClientSecret}&code= {授权码}
从下面的link解码ID令牌:
然后我就可以从ID令牌中成功获取preferred_username 属性了。
Microsoft 的 Jason Johnston(本教程的作者)回答 here:
The Azure team deployed a breaking change to their v2 auth endpoint, which is causing the preferred_username to not be present. You need to add profile to the SCOPES array in auth_helper.rb. I'll post an update to the tutorial after the Build conference.
auth_helper.rb 中的 SCOPES 数组现在看起来像这样:
SCOPES = [ 'openid', 'https://outlook.office.com/mail.read', 'profile' ]
我按照 this tutorial 进行了解码,并提取了电子邮件地址(应该存储在 preferred_username属性),即如下代码:
decoded_token = Base64.urlsafe_decode64(encoded_token)
jwt = JSON.parse(decoded_token)
email = jwt['preferred_username']
问题是返回的对象不包含这个属性,我得到的类似下面:
{
"ver":"2.0",
"iss":"https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0",
"aud":"0ab6433e-84fc-469b-8c72-41f7a0241a61",
"exp":1458142389,
"iat":1458055989,
"at_hash":"0OYaLKpTTdHNBrQNOqwQ0Q",
"sub":"AAAAAAAAAAAAAAAAAAAAAC1TrOaOmvInYrFAyrQjlFI",
"tid":"9188040d-6c67-4c5b-b112-36a304b66dad"
}
快速浏览 the spec 表明我正在从 Office 365 取回正确的对象,因为 preferred_username 被提及为潜在的声明,但是它不在我取回的对象中。
可能我没有使用正确的参数调用 get_token 函数,但是 the documentation for the library is pretty sparse,所以我真的不能说。
I have raised an issue on Github.
这是Office 365端的错误,教程的错误,还是我自己做错了?
我尝试使用普通 HTTP 请求重现此问题,但我可以成功获得 preferred_username 属性。
据我所知,只有当我们在请求中指定openid范围时,我们才能得到这个属性。为了缩小这个问题的范围,我建议您尝试在没有 Ruby.
的情况下使用 Fiddler 或 Postman下面是使用浏览器和Fiddler获取id token的测试,供大家参考:
- 使用Office 365账号在门户中注册应用(可参考教程)
- 通过下面的 link 在网络浏览器中获取授权码: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={ClientID}&response_type=code&redirect_uri={RedirectURL}&response_mode=query&scope=https%3A%2F%2Foutlook.office.com%2Fmail.read%20https%3A%2F%2Foutlook.office.com%2Fmail.send%20openid&state=12345
替换预览请求中的授权码并使用 Fiddler 来 post 获取令牌的请求:
POST: https://login.microsoftonline.com/common/oauth2/v2.0/token grant_type=authorization_code&client_id={ClientID}&scope=https%3A%2F%2Foutlook.office.com%2Fmail.read%20https%3A%2F%2Foutlook.office.com%2Fmail.send%20openid&redirect_uri=http%3A%2F%2Flocalhost%3A55065%2F&client_secret={ClientSecret}&code= {授权码}
从下面的link解码ID令牌:
然后我就可以从ID令牌中成功获取preferred_username 属性了。
Microsoft 的 Jason Johnston(本教程的作者)回答 here:
The Azure team deployed a breaking change to their v2 auth endpoint, which is causing the preferred_username to not be present. You need to add profile to the SCOPES array in auth_helper.rb. I'll post an update to the tutorial after the Build conference.
auth_helper.rb 中的 SCOPES 数组现在看起来像这样:
SCOPES = [ 'openid', 'https://outlook.office.com/mail.read', 'profile' ]