这个授权交换有什么问题?

时间:2015-02-09 17:05:55

标签: mediawiki azure-active-directory openid-connect

我已在Azure网站上设置了一个MediaWiki服务器,其中包含PluggableAuthOpenID Connect扩展名。后者使用PHP OpenID Connect Basic Client库。我是Azure AD域example.com的管理员,其中我创建了一个应用程序,其App 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. 知识产权响应

    (某些回应)

  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. 知识产权响应

    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. 知识产权响应

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

    AADSTS50001: Resource identifier is not provided.

  10. 请注意,如果我更改OpenID PHP客户端以提供'资源'在步骤8中,我从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. 知识产权响应

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

      (This has come up before.)

    3. 更新

      我根据@ jricher的建议取得了一些进展,但在经历了几次错误之后,我找到了一个我无法弄清楚的错误。完成所有操作后,我将向受影响的库提交拉取请求。

      这就是我所做的:

      • 我已将第二个应用程序添加到example.com Azure AD域,并将App ID URI设置为mediawiki://wiki.azurewebsites.net/,作为虚拟"资源& #34; 即可。我还授予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数据库升级脚本。谢天谢地,这是一个快速修复。

      • 之后,我现在离开(我希望是)试图从AAD的OpenID Connect UserInfo端点获取用户信息的最终问题。我&# 39;给它自己的部分。

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

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

      1. RP 请求:

        (已根据MSDNthe spec更新为使用带Authorization: Bearer标题的GET。)

        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.

        (如果我将#10更改为POST请求,正文中包含access_token,或者查询字符串中包含access_token的GET请求,则AAD返回错误:{ {1}}如果我使用AADSTS70000: Authentication failed. UserInfo token is not valid.的值代替我收到的id_token值,也会出现相同情况。)

      3. 帮助?

        更新

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

        我还有一个唠叨的部分,想知道OpenID Connect Basic Profile是否会变得更简单。我认为这就是为什么MediaWiki扩展没有实现的原因。

        更新2

        我刚遇到a new post from Vittorio Bertocci,其中包含有用的提示:

          

        ...在此请求中,应用程序正在为自己请求令牌!在Azure AD中,只有在请求的令牌是id_token ...

        时才可以这样做

        这表示只需将步骤8中的令牌请求类型从access_token更改为authorization_code,就可以消除对非标准id_token参数的需求,同时也可以制作丑陋的第二个AAD应用程序不必要。仍然是一个黑客,但它感觉不到一个。

3 个答案:

答案 0 :(得分:5)

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

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

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

...

希望这有帮助

答案 1 :(得分:3)

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

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

答案 2 :(得分: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