【发布时间】:2015-04-09 12:21:41
【问题描述】:
我在 Azure 网站上设置了一个带有 PluggableAuth 和 OpenID Connect 扩展名的 MediaWiki 服务器。后者使用PHP OpenID Connect Basic Client 库。我是 Azure AD 域 example.com 的管理员,我在其中创建了一个应用程序 ID URI、登录 URL 和回复 URL 都设置为 https://wiki.azurewebsites.net/ 的应用程序。当我导航到 wiki 时,我观察到以下行为(暂时省略了 cookie 值):
-
客户请求
GET https://wiki.azurewebsites.net/ HTTP/1.1 -
RP请求
GET https://login.windows.net/example.com/.well-known/openid-configuration -
IP响应
(一些回应)
-
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} -
客户请求
(跟随重定向)
-
IP响应
HTTP/1.1 302 Found Location: https://wiki.azurewebsites.net/?code={code}&state={state}&session_state={session_state} -
客户请求
(跟随重定向)
-
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} -
IP响应
(由 MediaWiki 解释;我目前没有记录完整的响应)
AADSTS50001: Resource identifier is not provided.
请注意,如果我在第 8 步中更改 OpenID PHP 客户端以提供“资源”参数,则会从 AAD 获得以下错误响应:
-
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} -
IP响应
AADSTS90027: The client '{client_id}' and resource 'https://wiki.azurewebsites.net/' identify the same application.
更新
根据@jricher 的建议,我已经取得了一些进展,但是在解决了几个错误之后,我遇到了一个我无法弄清楚的错误。完成这一切后,我将向受影响的库提交拉取请求。
这是我所做的:
我已将第二个应用程序添加到
example.comAzure AD 域,应用程序 ID URI 设置为mediawiki://wiki.azurewebsites.net/,作为虚拟“资源”。我还授予https://wiki.azurewebsites.net/应用程序对这个新应用程序的委派访问权限。在步骤 #8 中将虚拟应用程序的 URI 作为
resource参数 传递,我现在在 #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 步之后,执行一两个中间请求以获取用于验证令牌的元数据和密钥,会发生以下情况:
-
RP请求:
(更新为使用带有
Authorization: Bearer标头的GET,根据MSDN 和the spec。)GET https://login.windows.net/{tenant_id}/openid/userinfo Authorization: Bearer {access_token} -
IP响应:
400 Bad Request AADSTS50063: Credential parsing failed. AADSTS90010: JWT tokens cannot be used with the UserInfo endpoint.(如果我将 #10 更改为 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
我刚刚遇到了a new post from Vittorio Bertocci,其中包含这个有用的提示:
...在这个请求中,应用程序正在为自己请求一个令牌!在 Azure AD 中,仅当请求的令牌是 id_token 时才有可能...
这表明,只需将步骤 8 中的令牌请求类型从 authorization_code 更改为 id_token 就可以消除对非标准 resource 参数的需求,并且还不需要丑陋的第二个 AAD 应用程序。仍然是一个 hack,但感觉不像一个。
【问题讨论】:
-
"400 Bad Request" - Microsoft 可能正在寻找作为 POST 而不是作为 GET 的请求。你需要修改 PHP 库来改变它。
-
嗯,有趣的想法@user1949536,谢谢!
-
好吧,不仅有趣 - 它会与所有其他请求保持一致。 :)
-
仅供参考,我几乎可以正常工作:github.com/CyberNinjas/MW-OpenIdConnect 用户已通过身份验证并添加到用户表中。但由于某种原因,会话没有建立,我没有看到任何关于原因的错误。
-
更正,我有它的工作。我使用的 MediaWiki 的 REL1_27 显然不稳定。如果我输入 REL1_26,我的更新代码一切正常。
标签: mediawiki azure-active-directory openid-connect