这个授权交换有什么问题? [英] What's wrong with this authorization exchange?

查看:31
本文介绍了这个授权交换有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在 Azure 网站上使用 PluggableAuth 设置了 MediaWiki 服务器和 OpenID Connect 扩展.后者使用 PHP OpenID Connect Basic Client 库.我是 Azure AD 域 example.com 的管理员,其中我创建了一个应用程序 ID URI、登录 URL 和回复 URL 都设置为 https://wiki.azurewebsites.net/.当我导航到 wiki 时,我观察到以下行为(暂时省略了 cookie 值):

  1. 客户请求

    GET https://wiki.azurewebsites.net/HTTP/1.1

  2. RP请求

    GET https://login.windows.net/example.com/.well-known/openid-configuration

  3. IP响应

    (一些回应)

  4. RP响应

    HTTP/1.1 302 暂时移动位置:https://login.windows.net/{tenant_id}/oauth2/authorize?response_type=code&redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&client_id={client_id}&nonce={nonce}&state={state}

  5. 客户请求

    (跟随重定向)

  6. IP响应

    HTTP/1.1 302 找到位置:https://wiki.azurewebsites.net/?code={code}&state={state}&session_state={session_state}

  7. 客户请求

    (跟随重定向)

  8. RP请求(也重复#2 & #3)

    POST https://login.windows.net/{tenant_id}/oauth2/tokengrant_type=authorization_code&code={code}&redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&client_id={client_id}&client_secret={client_secret}

  9. IP响应

    (由 MediaWiki 解释;我目前没有记录完整的响应)

    AADSTS50001:未提供资源标识符.

请注意,如果我在第 8 步中更改 OpenID PHP 客户端以提供资源"参数,则会从 AAD 获得以下错误响应:

  1. RP请求

    POST https://login.windows.net/{tenant_id}/oauth2/tokengrant_type=authorization_code&code={code}&redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&resource=https%3A%2F%2Fwiki.azurewebsites.net%2F&client_id={client_id}&client_secret={client_secret}

  2. IP响应

    AADSTS90027:客户端{client_id}"和资源https://wiki.azurewebsites.net/"标识同一个应用程序.

    (这个已经出现过.)

更新

根据@jricher 的建议,我已经取得了一些进展,但是在解决了几个错误之后,我遇到了一个我无法弄清楚的错误.完成这一切后,我将向受影响的库提交拉取请求.

这是我所做的:

  • 我已将第二个应用程序添加到 example.com Azure AD 域,应用 ID URI 设置为 mediawiki://wiki.azurewebsites.net/,作为一个虚拟的资源".我还授予 https://wiki.azurewebsites.net/ 应用程序对这个新应用程序的委派访问权限.

  • 在第 8 步中将虚拟应用程序的 URI 作为 resource 参数 传递,我现在正在取回访问、刷新和 ID 令牌#9!

  • OpenID Connect 库要求对 ID 令牌进行签名,但当 Azure AD 对访问令牌进行签名时,它不会对 ID 令牌进行签名.它具有以下属性:{"typ":"JWT","alg":"none"}.所以我不得不修改库以允许调用者指定未签名的 ID 令牌被视为已验证".呜呜呜.

  • 好的,接下来发现无法验证声明,因为我指定的 OpenID Provider URL 和令牌中返回的颁发者 URL 不同.(说真的?!)因此,必须将提供程序指定为 https://sts.windows.net/{tenant_id}/,然后才能正常工作.p>

  • 接下来,我发现我还没有为 OpenID Connect 扩展运行 MediaWiki DB 升级脚本.谢天谢地,这是一个快速的解决方案.

  • 在那之后,我现在留下了(我希望是)尝试从 AAD 的 OpenID Connect UserInfo 端点获取用户信息的最后一个问题.我会给出它的自己的部分.

无法获取用户信息[更新]

这就是我现在卡住的地方.在第 9 步之后,执行一两个中间请求以获取用于验证令牌的元数据和密钥,会发生以下情况:

  1. RP请求:

    (更新为使用带有 Authorization: Bearer 标头的 GET,根据 MSDN规范.)

    GET https://login.windows.net/{tenant_id}/openid/userinfo授权:承载{access_token}

  2. IP响应:

    400 错误请求AADSTS50063:凭证解析失败.AADSTS90010:JWT 令牌不能与 UserInfo 端点一起使用.

    (如果我将 #1​​0 更改为 POST 请求,正文中包含 access_token,或者查询字符串中包含 access_token 的 GET 请求,AAD 返回错误:AADSTS70000: Authentication failed. UserInfo token is not valid. 如果我使用 id_token 的值代替 access_token 我收到的值.)

帮助?

更新

我仍然希望有人能阐明最后一个问题(UserInfo 端点不接受不记名令牌),但我可能会将其拆分为一个单独的问题.同时,我正在向库中添加一些解决方法(即将推出的 PR),以便可以使用已经在不记名令牌中返回的声明,而不是调用 UserInfo 端点.非常感谢所有为此提供帮助的人.

我还有一个烦人的部分,想知道如果使用 OpenID Connect 基本配置文件,整个事情会不会变得更简单.我认为 MediaWiki 扩展没有实现它是有原因的.

更新 2

我刚刚看到 一篇来自Vittorio Bertocci 包含这个有用的提示:

<块引用>

...在这个请求中,应用程序正在为自己请求一个令牌!在 Azure AD 中,仅当请求的令牌是 id_token 时才有可能...

这表明只需将步骤 8 中的令牌请求类型从 authorization_code 更改为 id_token 就可以消除对非标准 resource 的需求参数,也使丑陋的第二个 AAD 应用程序变得不必要.仍然是一个 hack,但感觉不像一个.

解决方案

贾斯汀是对的.对于授权代码授予流程,您必须在授权请求或令牌请求中指定资源参数.

使用 &resource=https%3A%2F%2Fgraph.windows.net%2F 获取 Azure AD Graph API 的访问令牌.

使用 &resource=https%3A%2F%2Fmanagement.core.windows.net%2F 获取 Azure 服务管理 API 的令牌.

...

希望对你有帮助

I've set up a MediaWiki server on an Azure website with the PluggableAuth and OpenID Connect extensions. The latter uses the PHP OpenID Connect Basic Client library. I am an administrator in the Azure AD domain example.com, wherein I've created an application with App ID URI, sign-on URL and reply URL all set to https://wiki.azurewebsites.net/. When I navigate to the wiki, I observe the following behavior (cookie values omitted for now):

  1. Client Request

    GET https://wiki.azurewebsites.net/ HTTP/1.1

  2. RP Request

    GET https://login.windows.net/example.com/.well-known/openid-configuration

  3. IP Response

    (some response)

  4. RP Response

    HTTP/1.1 302 Moved Temporarily Location: https://login.windows.net/{tenant_id}/oauth2/authorize?response_type=code&redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&client_id={client_id}&nonce={nonce}&state={state}

  5. Client Request

    (follows redirect)

  6. IP Response

    HTTP/1.1 302 Found Location: https://wiki.azurewebsites.net/?code={code}&state={state}&session_state={session_state}

  7. Client Request

    (follows redirect)

  8. RP Request (also repeats #2 & #3)

    POST https://login.windows.net/{tenant_id}/oauth2/token grant_type=authorization_code&code={code}&redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&client_id={client_id}&client_secret={client_secret}

  9. IP Response

    (As interpreted by MediaWiki; I don't have the full response logged at this time)

    AADSTS50001: Resource identifier is not provided.

Note that if I change the OpenID PHP client to provide the 'resource' parameter in step 8, I get the following error response from AAD instead:

  1. RP Request

    POST https://login.windows.net/{tenant_id}/oauth2/token grant_type=authorization_code&code={code}&redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&resource=https%3A%2F%2Fwiki.azurewebsites.net%2F&client_id={client_id}&client_secret={client_secret}

  2. IP Response

    AADSTS90027: The client '{client_id}' and resource 'https://wiki.azurewebsites.net/' identify the same application.

    (This has come up before.)

Update

I've made some progress based on @jricher's suggestions, but after working through several more errors I've hit one that I can't figure out. Once this is all done I'll submit pull requests to the affected libraries.

Here's what I've done:

  • I've added a second application to the example.com Azure AD domain, with the App ID URI set to mediawiki://wiki.azurewebsites.net/, as a dummy "resource". I also granted the https://wiki.azurewebsites.net/ application delegated access to this new application.

  • Passing in the dummy application's URI as the resource parameter in step #8, I'm now getting back the access, refresh, and ID tokens in #9!

  • The OpenID Connect library requires that the ID token be signed, but while Azure AD signs the access token it doesn't sign the ID token. It comes with the following properties: {"typ":"JWT","alg":"none"}. So I had to modify the library to allow the caller to specify that unsigned ID tokens are considered "verified". Grrr.

  • Okay, next it turns out that the claims can't be verified because the OpenID Provider URL I specified and the issuer URL returned in the token are different. (Seriously?!) So, the provider has to be specified as https://sts.windows.net/{tenant_id}/, and then that works.

  • Next, I found that I hadn't run the MediaWiki DB upgrade script for the OpenID Connect extension yet. Thankfully that was a quick fix.

  • After that, I am now left with (what I hope is) the final problem of trying to get the user info from AAD's OpenID Connect UserInfo endpoint. I'll give that its own section.

Can't get the user info [Updated]

This is where I am stuck now. After step #9, following one or two intermediate requests to get metadata and keys for verifying the token, the following occurs:

  1. RP Request:

    (Updated to use GET with Authorization: Bearer header, per MSDN and the spec.)

    GET https://login.windows.net/{tenant_id}/openid/userinfo Authorization: Bearer {access_token}

  2. IP Response:

    400 Bad Request AADSTS50063: Credential parsing failed. AADSTS90010: JWT tokens cannot be used with the UserInfo endpoint.

    (If I change #10 to be either a POST request, with access_token in the body, or a GET request with access_token in the query string, AAD returns the error: AADSTS70000: Authentication failed. UserInfo token is not valid. The same occurs if I use the value of the id_token in place of the access_token value that I received.)

Help?

Update

I'm still hoping someone can shed light on the final issue (the UserInfo endpoint not accepting the bearer token), but I may split that out into a separate question. In the meantime, I'm adding some workarounds to the libraries (PRs coming soon) so that the claims which are already being returned in the bearer token can be used instead of making the call to the UserInfo endpoint. Many thanks to everyone who's helped out with this.

There's also a nagging part of me that wonders if the whole thing would not have been simpler with the OpenID Connect Basic Profile. I assume there's a reason why that was not implemented by the MediaWiki extension.

Update 2

I just came across a new post from Vittorio Bertocci that includes this helpful hint:

...in this request the application is asking for a token for itself! In Azure AD this is possible only if the requested token is an id_token...

This suggests that just changing the token request type in step 8 from authorization_code to id_token could remove the need for the non-standard resource parameter and also make the ugly second AAD application unnecessary. Still a hack, but it feels like much less of one.

解决方案

Justin is right. For authorization code grant flow, your must specify the resource parameter in either the authorization request or the token request.

Use &resource=https%3A%2F%2Fgraph.windows.net%2F to get an access token for the Azure AD Graph API.

Use &resource=https%3A%2F%2Fmanagement.core.windows.net%2F to get a token for the Azure Service Management APIs.

...

Hope this helps

这篇关于这个授权交换有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆