是否可以将cognito的授权代码授予类型用作api网关中的授权者?

时间:2020-06-04 15:54:23

标签: oauth-2.0 aws-api-gateway amazon-cognito websecurity rest-security

我想知道有什么方法或可能性来实现授权代码授予类型作为Authroizer来保护API网关吗?正如搜索到的那样,最推荐使用“授权代码”授予类型来保护API。 我在下面的文章中找到了解释“使用cognito的“客户端凭据”作为授予类型来保护api网关的信息”,

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

我尝试了类似的方式来创建API网关,在集成之后我已经完成了该操作:

  1. 使用授权类型-“授权代码”在Cognito中创建用户池“ UI Hosted”

  2. 添加资源服务器

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

  4. 相关回电uri

现在,我可以访问登录页面进行注册和登录,并在回叫uri中返回“授权代码”

在API网关中

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

  2. 在用户池上方作为api网关中的授权者进行部署并

现在,当我在不传递令牌的情况下调用api时,它将返回“未经授权”

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

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

并使用邮递员在api标头中传递了令牌,但我仍然收到“未经授权”响应

所以想知道在api网关中需要执行哪些操作才能验证令牌,或者这种方法出了什么问题。?

是否有人可以为此提供帮助?

谢谢

2 个答案:

答案 0 :(得分:1)

您的API的作用是仅处理来自API客户端的传入访问令牌。 API不在乎用来获取令牌的流程。到目前为止,这是最常见的行为:

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

这里有一些示例代码,以防万一:

AWS API Gateway内置了对Cognito授权者的支持,如左下方的屏幕截图所示。 enter image description here

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

答案 1 :(得分:1)

最终我在这里得到了答案。

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

所以我在这里创建了一个简单的flask逻辑来交换身份验证代码,以从cognito获取“ id_token”,然后可以进一步传入api标头来获取响应。

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)