是否可以使用 cognito 的授权代码授权类型作为 api-gateway 中的授权方?

Is this possible to use cognito's Authorization code grant type as a authorizer in the api-gateway?

我想知道在保护 API 网关时是否有任何方法或可能性将授权码授予类型实施为 Authroizer?根据搜索,最推荐使用 'Authorization code' 授权类型来保护 API。 我发现下面的文章解释了使用 cognito 'client credentials' 作为授权类型来保护 api 网关,

https://medium.com/@awskarthik82/part-1-securing-aws-api-gateway-using-aws-cognito-oauth2-scopes-410e7fb4a4c0

我尝试了类似的方法来创建一个 API 网关,我在其中完成了以下集成:

  1. 已创建授权类型为 Cognito 的用户池 'UI Hosted' - 'Authorization code'

  2. 添加资源服务器

  3. 选择默认范围,因为我不想添加任何新范围

  4. 关联回调uri

现在我可以访问登录页面进行注册和登录,它 return 回调 uri'Authorization code' 中的

在API网关

  1. 我创建了一个 API 并集成了一些模拟响应

  2. 在 api 网关中作为授权者附加到用户池上方并部署

现在,当我在不传递令牌的情况下调用 api 时,它 returns 'Unauthorized'

所以我使用以下方法从 cognito 中提取访问令牌

How programtically exchange the authorization code to get the access token from cognito using python

并使用 post 人在 api header 中传递了令牌,但我仍然得到 'Unauthorized' 响应

所以想知道在 api 网关中需要做什么来验证令牌或者这种方法出了什么问题..?

感谢是否有人可以提供帮助?

谢谢

您的 API 的角色只是处理来自 API 客户端的传入访问令牌。 API 不关心使用什么流程来获取令牌。这是迄今为止最常见的行为:

  • UI 记录用户使用授权码流程——通常是 PKCE 变体
  • 这涉及 UI 调用授权服务器 - 例如 AWS Cognito
  • 登录完成后,UI 使用访问令牌/JWT
  • 调用 API 网关 URL
  • 然后 API 需要通过验证其签名来验证访问令牌

以下是一些示例代码,希望对您有所帮助:

AWS API Gateway 内置了对 Cognito 授权方的支持,如下面左侧的屏幕截图所示。

为了更好地控制行为,您可以改为在代码中创建一个自定义的 lambda 授权方,returns 一个 AWS 策略文档,如右侧的屏幕截图所示。我的 blog post 和上面的源代码 link 有一些更详细的信息,尽管它非常详细/高级。

终于找到答案了..

https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-user-pool-oauth-2-0-grants/

所以我在这里创建了一个简单的 flask 逻辑来交换授权代码以从 cognito 获取 'id_token',它可以进一步传入 api header 以获得响应。

def getToken(auth_code):
    response=''
    try:
        print("Code is", auth_code)
        response = requests.post(url + '/oauth2/token',{'Content-Type':'application/x-www-form-urlencoded', 'grant_type': grant_type, 'client_id': App_client_id,  'code': auth_code, 'redirect_uri': 'http://localhost:5000/login'})
        if response.status_code != 200:
            return "Not a valid response"
        print("Response is", response.json())
        token_value = response.json()
        print("Token value", token_value['id_token'])
        return token_value['id_token']

    except TypeError as e:
        print("Error is",e)