Cloudformation Cognito - 如何通过SAM模板设置App Client设置,域和联合身份

时间:2018-03-28 00:57:20

标签: amazon-web-services yaml amazon-cloudformation sam cognito

我已经使用了我的cognito用户池cloudformation模板,并将其集成到我的api网关中。但不知何故,我仍然需要手动配置应用客户端设置,域和联合身份,以便为用户提供有效的登录门户。我一直在寻找自动化这些的可能解决方案,但我似乎找不到任何接近它的东西。

我想通过cloudformation sam模板自动配置应用客户端设置,域和联合身份,因此我不必手动执行这些操作。

非常感谢任何建议。谢谢。

(已发布附件以获取更多信息)

8 个答案:

答案 0 :(得分:27)

我创建了两个CloudFormation自定义资源来应用Cognito应用程序客户端设置和域名。有了这些资源,您可以拥有一个像这样的脚本:

UserPoolTestClient:
  Type: 'AWS::Cognito::UserPoolClient'
  Properties:
    ClientName: UserPoolTestClient
    GenerateSecret: true
    UserPoolId: !Ref UserPoolTest
UserPoolTestClientSettings:
  Type: 'Custom::CognitoUserPoolClientSettings'
  Properties:
    ServiceToken: !GetAtt CloudFormationCognitoUserPoolClientSettings.Arn
    UserPoolId: !Ref UserPoolTest
    UserPoolClientId: !Ref UserPoolTestClient
    SupportedIdentityProviders:
      - COGNITO
    CallbackURL: 'https://www.amazon.com'
    LogoutURL: 'https://www.google.com'
    AllowedOAuthFlowsUserPoolClient: true
    AllowedOAuthFlows:
      - code
    AllowedOAuthScopes:
      - openid
UserPoolTestDomain:
  Type: 'Custom::CognitoUserPoolDomain'
  Properties:
    ServiceToken: !GetAtt CloudFormationCognitoUserPoolDomain.Arn
    UserPoolId: !Ref UserPoolTest
    Domain: 'userpool-test-01'

完整的代码是here

答案 1 :(得分:17)

看起来没有办法提供 App整合 - >域名联盟 - >身份提供商通过CloudFormation。

我发现只有User Pool Client常规设置 - >应用客户端)的引用,但它不会配置应用程序集成 - >应用客户端设置

如果您需要为用户池自动执行提供Domain nameIdentity providersApp client settings的过程,您可以通过创建自定义脚本(AWS CLI)或Lambda(AWS SDK)来实现这应该在堆栈部署后执行。


更新

查看显示excellent example与Lambda一起使用的answer belowCloudFormation Custom Resources)。

答案 2 :(得分:4)

从昨天开始,AWS CloudFormation添加了对直接配置域名,身份和其他设置的本机支持: https://aws.amazon.com/about-aws/whats-new/2019/10/amazon-cognito-increases-cloudformation-support/

  

这项新的支持包括能够直接在CloudFormation中安全,自动地配置托管UI域,配置托管UI的自定义,配置IdentityProvider,配置高级安全功能的行为以及配置资源服务器的能力。

(感谢我的同事Bernhard的这次更新)

答案 3 :(得分:2)

CloudFormation已添加资源AWS::Cognito::UserPoolDomain来管理用户池域:

Type: AWS::Cognito::UserPoolDomain
Properties: 
  CustomDomainConfig: 
     CertificateArn: !Ref CertificateArn
  Domain: "your.custom.domain.com"
  UserPoolId: !Ref UserPool

此外,AWS::Cognito::UserPoolClient中已经添加了配置:

Type: AWS::Cognito::UserPoolClient
Properties: 
  AllowedOAuthFlows: 
    - String
  AllowedOAuthFlowsUserPoolClient: Boolean
  AllowedOAuthScopes: 
    - String
  AnalyticsConfiguration: 
    AnalyticsConfiguration
  CallbackURLs: 
    - String
  ClientName: String
  DefaultRedirectURI: String
  ExplicitAuthFlows: 
    - String
  GenerateSecret: Boolean
  LogoutURLs: 
    - String
  ReadAttributes: 
    - String
  RefreshTokenValidity: Integer
  SupportedIdentityProviders: 
    - String
  UserPoolId: String
  WriteAttributes: 
    - String

答案 4 :(得分:1)

我想添加一个不同的解决方案(由Mickael建议),因为CloudFormation的设置很复杂;创建CloudFormation堆栈后,此命令行将创建您的域:

 aws cognito-idp create-user-pool-domain --domain test-domain --user-pool-id eu-west-1_xxxxxxxx 

在自动部署中,您可以添加用于设置域的脚本。不如CF上的所有功能强大,但可以正常工作

答案 5 :(得分:1)

非常受罗斯伯格·林哈雷斯(Rosberg Linhares)示例的启发,但使用python并使用AWS cfn helper模块:

如果使用此代码编写lambda函数,则基本上是使用boto3进行客户端应用设置

from crhelper import CfnResource
import boto3
from copy import copy

# setup the cfn helper 
helper = CfnResource()
client = boto3.client('cognito-idp')

# these wrappers return the function unaltered, so we can chain them to apply
# the function in both create and update
@helper.create
@helper.update
def update_on_create(event, _):

        params = copy(event['ResourceProperties'])
        del params['ServiceToken']

        client.update_user_pool_client(**params) 

# don't do anything on delete. Deleting the client app is handled by the template
@helper.delete
def delete_user_pool_client(event, _):
        pass


def handler(event, context):
    helper(event, context)

然后您的云信息将类似,例如

UserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      ClientName: 'TestClient'
      GenerateSecret: true
      UserPoolId: !Ref UserPool
  UserPoolClientSettings:
    Type: Custom::CognitoUserPoolClientSettings
    DependsOn: 
        - LambdaForAppClientSettings
        - UserPoolClient
    Properties:
      ServiceToken: !GetAtt LambdaForAppClientSettings.Arn
      UserPoolId: !Ref UserPool
      ClientId: !Ref UserPoolClient
      CallbackURLs: 
          - https://www.amazon.com
      SupportedIdentityProviders:
          - COGNITO 

由于client.update_user_pool_client(**params)中的参数扩展,您可能会为update_user_pool_client()指定一些或所有参数,这可能带来好处。您必须确保cloudformation定制资源的Properties映射中的键完全匹配boto3所需的键。检查boto3 documentation以获得可能的参数列表。

答案 6 :(得分:1)

正如 matsev 和 Gregor 所指出的,这现在可以通过 cloudformation 轻松完成。这意味着已接受的答案以及与已接受的答案相关联的答案在此期间已被弃用。

查看文档:

  1. UserPoolIdentityProvider
  2. UserPoolClient
  3. UserPoolDomain

这是我自己的模板中的一个示例:

  UserPoolClient:
    Type: "AWS::Cognito::UserPoolClient"
    Properties:
      ClientName: !Sub ${AppName}-${Env}-appsync-client
      GenerateSecret: false
      UserPoolId: !Ref UserPool
      SupportedIdentityProviders:
        - COGNITO
        - Facebook
        #- SignInWithApple
        - Google
      AllowedOAuthFlowsUserPoolClient: true
      AllowedOAuthFlows: 
        - code
      AllowedOAuthScopes:
        - email
        - openid
        - profile
        - aws.cognito.signin.user.admin 
      CallbackURLs: 
        - !Sub ${AppName}://
      DefaultRedirectURI: !Sub ${AppName}://
      LogoutURLs: 
        - !Sub ${AppName}://
    DependsOn: 
      - GoogleCognitoUserPoolIdentityProvider
      #- AppleUserPoolIdentityProvider
      - FacebookCognitoUserPoolIdentityProvider

  CognitoUserPoUserPoolDomain: 
    Type: AWS::Cognito::UserPoolDomain 
    Properties:
      UserPoolId: !Ref UserPool 
      Domain: !Sub ${AppName}-${Env}

  FacebookCognitoUserPoolIdentityProvider:
    Type: AWS::Cognito::UserPoolIdentityProvider
    Properties:
      ProviderName: Facebook
      AttributeMapping:
        email: email
      ProviderDetails:
        client_id: TODOYourFacebookAppId
        client_secret: TODOYourFacebookAppSecret
        authorize_scopes: email,public_profile
      ProviderType: Facebook
      UserPoolId: !Ref UserPool
    
  GoogleCognitoUserPoolIdentityProvider:
    Type: AWS::Cognito::UserPoolIdentityProvider
    Properties:
      ProviderName: Google
      AttributeMapping:
        email: email
      ProviderDetails:
        client_id: TODOYourGoogleAppId
        client_secret: TODOYourGoogleAppSecret
        authorize_scopes: email openid profile
      ProviderType: Google
      UserPoolId: !Ref UserPool

答案 7 :(得分:0)

我为自己和其他想要试一试的确切3种资源推出了解决方案。 https://github.com/cyrfer/cloudformation-custom-resource-provider