AWS API Gateway-将访问令牌与Cognito用户池授权器一起使用?

m4pnthwp  于 2022-09-21  发布在  其他
关注(0)|答案(4)|浏览(155)

我正在配置一个具有各种前端(移动和网络应用)和单个API后端的应用程序,该应用程序由Lambda提供支持,并通过AWS API Gateway访问。

由于我计划使用Cognito对用户进行身份验证和授权,因此我已经在我的API Gateway上设置了一个Cognito用户池授权器和几个API方法。

有了这样的架构,从OAuth的Angular 来看,我的应用程序(例如iOS或Vue.js应用程序)是客户端应用程序,而我的API Gateway后端是资源服务器似乎是合乎逻辑的。基于this Auth0 forum post,似乎很明显,我应该在我的客户端应用程序中使用ID令牌,并传递访问令牌来授权我的API Gateway资源。

当我点击Cognito /oauth2/authorize端点获取访问代码并使用该代码点击/oauth2/token端点时,我得到了3个令牌--一个访问令牌、一个ID令牌和一个刷新令牌。到目前为止一切都很好,因为我应该得到我需要的东西。

这就是我遇到困难的地方-使用API Gateway Cognito User Pool Authorizer控制台上的测试功能,我可以粘贴ID令牌,它就会通过(在屏幕上解码令牌)。但是当我粘贴访问令牌时,我得到401 - unauthorized

在我的Cognito设置中,我只使用emailopenid作用域启用了Authorization Code Grant流(这似乎是Cognito允许的最小值,因为我尝试在没有勾选这些作用域的情况下保存时出错)。

我需要添加一些特定的作用域才能让API Gateway使用访问代码授权请求吗?如果是,这些配置在哪里?

还是我错过了什么?API Gateway是否只允许ID令牌与Cognito用户池授权程序一起使用?

v09wglhw

v09wglhw1#

您可以使用具有与id令牌相同的授权者的访问令牌,但在用户池和APIG中还需要进行一些额外的设置。

即使完成了这个额外的设置,您也不能将内置的授权器测试功能与访问令牌一起使用,而只能使用ID令牌。来自AWS的典型80%解决方案!

要使用访问令牌,您需要在App Integration -> Resource Servers下的用户池中设置资源服务器,使用什么并不重要,但我假设您使用<site>.com作为标识符,并且您有一个名为api的作用域。

否转到APIG中的方法并输入该方法的Method Request。假设已经设置了使用id标记测试的授权器,然后将<site>.com/api添加到Settings -> OAuth Scopes部分。

只需添加OAuth作用域,就可以确保令牌现在必须是访问令牌,而不再接受ID令牌。

详细说明如下:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html

lyfkaqu1

lyfkaqu12#

对于那些正在寻找答案但没有使用OAuth并使用无服务器框架进行部署的人:

让APGW接受accesToken的有效方法是修改我的serverless.yml文件,如下所示:

functions:
  my-function:
    handler: path to source file
    events:
      - http:
          path: my-function
          method: post
          cors: true
          authorizer:
            type: COGNITO_USER_POOLS
            scopes:
              - YOUR SCOPE HERE <- THIS IS THE TRICK
            authorizerId:
              Ref: ApiGatewayAuthorizer

可以通过读取访问令牌的内容(通过将令牌粘贴到https://jwt.io/调试器中)找到作用域的值。

3zwtqj6y

3zwtqj6y3#

可以,API网关只会使用idToken进行授权。

用户输入正确的凭据后,身份提供者会提供访问代码,授权用户输入正确的凭据,客户端使用此访问代码只是为了从/oauth2/token终结点获取该给定用户的idToken和renhToken。您的所有进一步调用都将只在Authorization头中使用idToken。

即使该访问代码在您检索用户令牌后也会过期。

kyxcudwk

kyxcudwk4#

如果有人对如何在CDK中实现这一点感到好奇,下面是我如何成功地创建了一个API,该API接受一个auth令牌作为Authorization头的一部分。上面有一些关于它如何在概念上工作的好信息。由于不可避免地缺少AWS CDK文档,我通过查找Map到上面提到的概念的构造并迭代地将正确的构造添加到API和用户池中,找到了CDK的方法。

创建用户池

const userPool = new cognito.UserPool(this, "****");

创建资源服务器和作用域。稍后为API方法分配自定义作用域时,这些作用域将非常重要。标识符-AWS建议使用域名

const apiScope = new cognito.ResourceServerScope({
  scopeName: '**',
  scopeDescription: '**'
});

const userServer = userPool.addResourceServer('**', {
  identifier: props.subdomain,
  scopes: [apiScope]
});

创建托管的UI域。用户将登录到托管的用户界面以获得在认证码身份验证流中使用的认证码,并接收ID/访问令牌。

userPool.addDomain('**', {
  cognitoDomain: {
    domainPrefix: '**',
  },
});

创建客户端,配置所需的授权流,并分配您希望允许用户使用的OAuth作用域。

const userPoolClient = userPool.addClient('**', {
  authFlows: {
    adminUserPassword: true
  },
  supportedIdentityProviders: [
    cognito.UserPoolClientIdentityProvider.COGNITO
  ],
  oAuth: {
    flows: {
      authorizationCodeGrant: true,
      implicitCodeGrant: true
    },
    scopes: [
      cognito.OAuthScope.resourceServer(userServer, apiScope),
      cognito.OAuthScope.OPENID,
      cognito.OAuthScope.COGNITO_ADMIN
    ]
  },
  refreshTokenValidity: Duration.days(10)
});

此时,您可以在AWS控制台的用户池->用户池名称>应用集成->应用客户端列表->应用客户端名称>托管用户界面->自定义作用域下部署应用程序并查看作用域。作用域是资源服务器ID和作用域名称的组合。

为用户池创建Cognito用户池授权器

const authorizer = new apigateway.CognitoUserPoolsAuthorizer(this, '**', {
  cognitoUserPools: [userPool]
});

将授权器添加到您的API的适当方法。确保添加正确的授权作用域。

const api = new apigateway.RestApi(this, '***', {
  ...options
});
const resource = api.root.addResource('resource');

resource.addMethod('POST', integration, {
  authorizer,
  authorizationScopes: [
    <scope names>
  ]
});

添加正确的授权作用域是至关重要的,这也是我一度陷入困境的地方。这需要与上面创建的至少一个自定义资源服务器作用域匹配。

相关问题