4

我已经使用PluggableAuthOpenID Connect扩展在 Azure 网站上设置了一个 MediaWiki 服务器。后者使用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 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. 客户要求

    (跟随重定向)

  6. IP响应

    HTTP/1.1 302 Found Location: 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/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响应

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

    AADSTS50001: Resource identifier is not provided.

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

  1. RP请求

    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响应

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

    (这个以前出现过。)

更新

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

这是我所做的:

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

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

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

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

  • 接下来,我发现我还没有为 OpenID Connect 扩展运行 MediaWiki DB 升级脚本。谢天谢地,这是一个快速修复。

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

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

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

  1. RP请求:

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

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

  2. 知识产权回应:

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

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

帮助?

更新

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

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

更新 2

我刚刚看到Vittorio Bertocci 的一篇新帖子,其中包含了这个有用的提示:

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

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

4

3 回答 3

5

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

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

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

...

希望这可以帮助

于 2015-02-10T07:16:01.720 回答
3

Microsoft 的 OpenID Connect(和 OAuth2)实现有一个已知错误,它需要resource客户端发送参数。这是一个特定于 MS 的参数,不幸的是,它破坏了与几乎所有主要 OAuth2 和 OpenID Connect 库的兼容性。我知道 MS 意识到了这个问题(我一直在尝试与他们的团队进行互操作性测试已经有一段时间了),但我不知道有任何解决问题的计划。

因此,与此同时,您唯一真正的途径是破解您的客户端软件,以便它发送一个resourceAS 将接受的参数。看起来您设法让它发送参数,但没有发送它喜欢的值。

于 2015-02-09T20:28:44.547 回答
1

我在 Azure 上运行它时遇到了问题,即使我在本地运行了一些东西。由于无论如何我都在尝试设置私有 wiki,因此我最终通过打开以下选项为整个站点启用了 Azure AD 保护:

All Settings -> Features -> Authentication / Authorization

https://portal.azure.com的网站内

这使得您必须先对 Azure-AD 进行身份验证,然后才能看到该站点的任何页面。一旦您通过身份验证,就会使用您的用户名为应用程序设置一堆 HTTP 标头,包括 REMOTE_USER。因此,我使用以下插件自动将已通过身份验证的用户登录到 Azure:

https://www.mediawiki.org/wiki/Extension:Auth_remoteuser

于 2016-05-23T20:35:42.253 回答