如何使用 Oauth 2.0(Connexion、Swagger)更改 "scopes"

How to change "scopes" with Auth2.0 (Connexion, Swagger)

我想用 OAuth2.0 理解这个 authentication-example 并且卡在范围部分: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 的 security-definitions 中,“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”是 returned 并且作用域实际上是我们想要的“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 上调用本地主机时,security-part 检查需要什么并看到“uid” .它跟在 localhost:7979 上的 x-tokenInfoUrl 之后,我们在那里启动了 mock_tokeninfo 应用程序,它 return 给我们一个“uid”和范围“uid”。

现在我的问题如下:我现在有自己的身份提供者,想从那里访问用户信息。我将 x-tokenInfoUrl 更改为如下内容: https://<my_idp>/<some_paths>/userinfo 当我像这样卷曲时:curl -H 'Authorization: Bearer <access_token>‘ https://<IDP>/<some_paths>/userinfo,它起作用了,我得到的响应看起来像这样:

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

现在据我了解,我只需要将“uid”更改为例如“邮件”,它应该 return 我的电子邮件给我,但没有:我收到

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

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

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

编辑:

请 - 帮助我 Whosebug 的聪明人:(

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

我检查了 header 是否确实被重定向了。

我发现了这个声明:“然而,为了明确这一点,你应该在这种情况下分配 uid 伪权限。它是用户 ID,并且始终作为 OAuth2 默认范围可用”,但是再次 - 如果这是 pseudo-permission,我如何做一个正常的作用域?

在我找到的每个示例中(pet-read/write 示例是最常见的一个),scope-variables 似乎有自定义名称...(https://swagger.io/docs/specification/authentication/oauth2/)

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

所以终于找到解决办法了。问题是文档没有更新。这是文档的 link:

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

它说:

The sub property of the Token Info response will be passed in the user argument to the handler function.

进一步调查发现连接包的这条提交消息:

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

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

The Token Info response will be passed in the token_info argument to the handler function. The sub property of the Token Info response will be passed in the user argument to the handler function.

所以把关于“No Scopes”的信息放在这里:

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”而不是“user”:

app.py:

get_secret(token_info):
    return token_info

通过这种方式,我得到了我们的身份提供者传递的所有信息。

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