Cloudformation Cognito - 如何通过 SAM 模板设置应用程序客户端设置、域和联合身份
Cloudformation Cognito - how to setup App Client Settings, Domain, and Federated Identities via SAM template
我的 cognito 用户池 cloudformation 模板已经运行,并将其集成到我的 api 网关中。但不知何故,我仍然需要手动配置应用程序客户端设置、域和联合身份,以便为用户提供一个有效的登录门户。我一直在这里和那里寻找自动化这些的可能解决方案,但我似乎找不到任何接近它的东西。
我想通过 cloudformation sam 模板自动配置应用程序客户端设置、域和联合身份,因此我不必手动执行这些操作。
非常感谢任何建议。谢谢。
(附加信息已发布附件)
- https://i.stack.imgur.com/I7NSt.png
- https://i.stack.imgur.com/ZbiTI.png
- https://i.stack.imgur.com/F8rfH.png
更新:自 2019 年底以来,AWS Cloudformation 原生支持应用程序客户端设置、域和联合身份。查看其他答案。
看起来无法通过 CloudFormation 提供应用程序集成 -> 域名 和联合 -> 身份提供商。
我只找到了 User Pool Client 的参考(常规设置 -> 应用程序客户端),但它不会配置 应用程序集成 -> 应用程序客户端设置.
如果您需要自动化为用户池提供 Domain name, Identity providers and App client settings 的过程,您可以通过创建自定义脚本 (AWS CLI) 或 Lambda (AWS SDK) 来实现,这应该在堆栈部署后执行。
**更新**
使用 Lambda 查看 excellent example () that shows usage of CloudFormation Custom Resources。
我创建了两个 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.
我想添加一个不同的解决方案(由 Mickael 建议),因为 CloudFormation 的设置很复杂;此命令行将在创建 CloudFormation 堆栈后创建您的域:
aws cognito-idp create-user-pool-domain --domain test-domain --user-pool-id eu-west-1_xxxxxxxx
在您的自动部署中,您可以添加一个脚本来设置您的域。不如 CF 上的所有东西那么好,但它有效
我为自己和其他想要试一试的人推出了针对这 3 种资源的解决方案。
https://github.com/cyrfer/cloudformation-custom-resource-provider
受到 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)
那么你的 cloudformation 将是类似的,例如
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 以获得可能的参数列表。
从昨天开始,AWS CloudFormation 添加了对直接配置域名、身份和其他设置的原生支持:
https://aws.amazon.com/about-aws/whats-new/2019/10/amazon-cognito-increases-cloudformation-support/
This new support includes the ability to securely and automatically configure a hosted UI domain, configure customization for a hosted UI, configure an IdentityProvider, configure the behavior of advanced security features and configure resource servers, all directly within CloudFormation.
(感谢我的同事 Bernhard 的更新)
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
正如 matsev 和 Gregor 所指出的,这现在可以通过 cloudformation 轻松完成。这意味着接受的答案和链接到接受的答案的答案同时被弃用。
查看文档:
这是我自己模板中的示例:
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
我的 cognito 用户池 cloudformation 模板已经运行,并将其集成到我的 api 网关中。但不知何故,我仍然需要手动配置应用程序客户端设置、域和联合身份,以便为用户提供一个有效的登录门户。我一直在这里和那里寻找自动化这些的可能解决方案,但我似乎找不到任何接近它的东西。
我想通过 cloudformation sam 模板自动配置应用程序客户端设置、域和联合身份,因此我不必手动执行这些操作。
非常感谢任何建议。谢谢。
(附加信息已发布附件)
- https://i.stack.imgur.com/I7NSt.png
- https://i.stack.imgur.com/ZbiTI.png
- https://i.stack.imgur.com/F8rfH.png
更新:自 2019 年底以来,AWS Cloudformation 原生支持应用程序客户端设置、域和联合身份。查看其他答案。
看起来无法通过 CloudFormation 提供应用程序集成 -> 域名 和联合 -> 身份提供商。
我只找到了 User Pool Client 的参考(常规设置 -> 应用程序客户端),但它不会配置 应用程序集成 -> 应用程序客户端设置.
如果您需要自动化为用户池提供 Domain name, Identity providers and App client settings 的过程,您可以通过创建自定义脚本 (AWS CLI) 或 Lambda (AWS SDK) 来实现,这应该在堆栈部署后执行。
**更新**
使用 Lambda 查看 excellent example (
我创建了两个 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.
我想添加一个不同的解决方案(由 Mickael 建议),因为 CloudFormation 的设置很复杂;此命令行将在创建 CloudFormation 堆栈后创建您的域:
aws cognito-idp create-user-pool-domain --domain test-domain --user-pool-id eu-west-1_xxxxxxxx
在您的自动部署中,您可以添加一个脚本来设置您的域。不如 CF 上的所有东西那么好,但它有效
我为自己和其他想要试一试的人推出了针对这 3 种资源的解决方案。 https://github.com/cyrfer/cloudformation-custom-resource-provider
受到 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)
那么你的 cloudformation 将是类似的,例如
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 以获得可能的参数列表。
从昨天开始,AWS CloudFormation 添加了对直接配置域名、身份和其他设置的原生支持: https://aws.amazon.com/about-aws/whats-new/2019/10/amazon-cognito-increases-cloudformation-support/
This new support includes the ability to securely and automatically configure a hosted UI domain, configure customization for a hosted UI, configure an IdentityProvider, configure the behavior of advanced security features and configure resource servers, all directly within CloudFormation.
(感谢我的同事 Bernhard 的更新)
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
正如 matsev 和 Gregor 所指出的,这现在可以通过 cloudformation 轻松完成。这意味着接受的答案和链接到接受的答案的答案同时被弃用。
查看文档:
这是我自己模板中的示例:
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