首页 > 解决方案 > 如何使用 Auth2.0 (Connexion, Swagger) 更改“范围”

问题描述

我很想用 OAuth2.0 理解这个身份验证示例,并被困在范围部分:https ://github.com/zalando/connexion/tree/master/examples/swagger2/oauth2

在 app.yaml 中,我们将 'uid' 定义为我们应用程序的必要范围:

  /secret:
    get:
      summary: Return secret string
      operationId: app.get_secret
      responses:
        200:
          description: secret response
          schema:
            type: string
      security:
        # enable authentication and require the "uid" scope for this endpoint
        - oauth2: ['uid']

在 app.yaml 的安全定义中,“uid”再次位于范围部分,并且需要作为 x-tokenInfoUrl 的答案(我需要)。

securityDefinitions:
  oauth2:
    type: oauth2
    flow: implicit
    authorizationUrl: https://example.com/oauth2/dialog
    x-tokenInfoUrl: http://localhost:7979/tokeninfo
    scopes:
      uid: Unique identifier of the user accessing the service.

在我们的 tokeninfo 模拟应用程序 (mock_tokeninfo.yaml) 中,我们看到返回了“uid”并且范围实际上是我们想要的“uid”。

return {'uid': uid, 'scope': ['uid']}

最后在 mock_tokeninfo.yaml 中,我们在响应中有“uid”和范围:

      responses:
        200:
          description: Token info object
          schema:
            type: object
            properties:
              uid:
                type: string
              scope:
                type: array
                items:
                  type: string

所以我现在理解的是,当 app.py 在端口 8080 上启动并使用“/secret”在端口 8080 上调用 localhost 时,安全部分会检查所需内容并看到“uid”。它遵循 localhost:7979 上的 x-tokenInfoUrl,我们在那里启动了我们的 mock_tokeninfo 应用程序,它返回给我们一个“uid”和范围“uid”。

现在我的问题如下:我现在有一个自己的身份提供者,并想从那里访问用户信息。我将 x-tokenInfoUrl 更改为类似这样的内容: https://<my_idp>/<some_paths>/userinfo 当我像这样进行 curl 时curl -H 'Authorization: Bearer <access_token>‘ https://<IDP>/<some_paths>/userinfo,它可以工作,并且我得到如下响应:

{"mail":"<my_email>",
"name":"<my_name>"}

现在据我了解,我只需要将“uid”更改为“mail”,它应该将我的电子邮件返回给我,但没有:我得到

403 - forbidden
provided token does not have the required scope
Content-Type: application/problem+json

我不明白为什么我没有所需的范围 - 这对我来说根本没有意义。有人可以解释一下,我怎样才能从我的身份提供者那里获取我的信息?我还检查并在我的授权电子邮件中使用我的 id 和秘密,它说范围是 <some_keyword>,但是这个关键字也会像其他所有内容一样导致 403。

Ps:我已经将证书传递给身份提供者,所以这应该不是问题。

编辑

请 - 帮助我你 StackOverflow 的聪明人 :(

我发现了那些“必须为范围命名约定”:https ://opensource.zalando.com/restful-api-guidelines/ 但它也没有帮助。

我检查了标头是否真的被重定向了。

我找到了这样的声明:“但是,为了明确这一点,您应该在这种情况下分配 uid 伪权限。它是用户 ID,并且始终可用作 OAuth2 默认范围”,但同样 - 如果这是一个伪权限,怎么办我做一个正常的范围?

在我发现的每个示例中(宠物读/写示例是最常见的示例),范围变量似乎都有自定义名称......(https://swagger.io/docs/specification/authentication/oauth2/ )

这里是“安全”部分的文档,也许我误解了一些东西:https ://connexion.readthedocs.io/en/latest/security.html

标签: oauth-2.0scopeswaggeraccess-tokenconnexion

解决方案


所以最终找到了解决方案。问题是文档没有更新。这是文档的链接:

https://connexion.readthedocs.io/en/latest/security.html#oauth-2-authentication-and-authorization

它说:

令牌信息响应的子属性将在用户参数中传递给处理函数。

进一步调查导致发现 connexion-package 的此提交消息:

https://github.com/mnylen/connexion/commit/1818c34ecbdd6833a6c8cde61021ece38b59d978

这更新了该短语的不充分描述:

Token Info 响应将在token_info参数中传递给处理函数。Token Info 响应的sub属性将在user 参数中传递给处理函数。

因此,从这里放置有关“无范围”的信息:

https://swagger.io/docs/specification/authentication/oauth2/

连同来自提交消息的信息,我们可以更改我们的示例,如下所示:

app.yaml:

security:
    # enable authentication and require the "uid" scope for this endpoint
    - oauth2: []

securityDefinitions:
  oauth2:
    type: oauth2
    x-tokenInfoUrl: https://<my_idp>/<some_paths>/userinfo
    scopes: {}

而不是使用“用户”,我们在函数中使用“token_info”:

app.py:

get_secret(token_info):
    return token_info

这样,我就得到了我们的身份提供者传递的所有信息。

谢谢大家和我一起思考 :) 希望,你觉得这很有用。


推荐阅读