如何通过SAM模板自动化配置Cognito应用客户端设置、域名及联合身份
我帮你整理了一套完整的配置方案,能把你目前手动操作的步骤全部自动化——包括应用客户端设置、用户池域名和联合身份池的配置,直接整合到你现有的CloudFormation/SAM模板里就行:
1. 自动化配置Cognito应用客户端
用AWS::Cognito::UserPoolClient资源就能搞定应用客户端的所有设置,包括OAuth流程、回调/注销URL、支持的身份提供商等:
Resources: MyCognitoUserPoolClient: Type: AWS::Cognito::UserPoolClient Properties: UserPoolId: !Ref MyExistingUserPool # 替换成你现有用户池的资源名称 ClientName: MyAppClient GenerateSecret: false # 单页应用建议设为false,服务器端应用可设为true AllowedOAuthFlows: - code # 授权码流程,适合需要服务器端处理令牌的场景;SPA可添加implicit AllowedOAuthScopes: - openid - email - profile AllowedOAuthFlowsUserPoolClient: true # 启用OAuth流程支持 CallbackURLs: - "https://your-app-domain.com/callback" # 替换成你的实际回调地址 LogoutURLs: - "https://your-app-domain.com/logout" # 替换成你的实际注销地址 SupportedIdentityProviders: - COGNITO # 后续要加Google/Facebook等联合登录,直接在这里添加对应的标识(比如Google)
关键参数说明:
AllowedOAuthFlows和AllowedOAuthScopes是和API网关集成的核心,确保用户能通过OAuth流程获取合法令牌访问你的APISupportedIdentityProviders可以直接扩展第三方登录,不需要手动在控制台添加
2. 自动化配置Cognito用户池域名
用AWS::Cognito::UserPoolDomain资源可以配置两种类型的域名:AWS托管的默认域名,或者你的自定义域名:
方案1:AWS托管域名
MyCognitoUserPoolDomain: Type: AWS::Cognito::UserPoolDomain Properties: UserPoolId: !Ref MyExistingUserPool Domain: "my-unique-login-prefix" # 自定义前缀,最终域名是 https://my-unique-login-prefix.auth.{region}.amazoncognito.com
方案2:自定义域名
如果要用自己的域名,需要先在ACM申请证书(必须在us-east-1区域,因为Cognito托管UI依赖该区域的证书服务),然后配置:
MyCognitoUserPoolDomain: Type: AWS::Cognito::UserPoolDomain Properties: UserPoolId: !Ref MyExistingUserPool CustomDomainConfig: CertificateArn: !Ref MyCustomDomainCertificate # 引用你的ACM证书ARN Domain: "login.your-domain.com" # 你的自定义域名
注意:自定义域名需要完成DNS解析,把CNAME记录指向Cognito提供的目标地址,模板部署后可以在控制台查看对应的解析目标,或者用CloudFormation的
AWS::Route53::RecordSet资源自动化DNS配置。
3. 自动化配置联合身份池(Cognito Identity Pool)
用AWS::Cognito::IdentityPool和AWS::Cognito::IdentityPoolRoleAttachment资源可以完成联合身份池的配置,关联你的用户池,并定义用户角色权限:
# 创建身份池 MyCognitoIdentityPool: Type: AWS::Cognito::IdentityPool Properties: IdentityPoolName: MyAppIdentityPool AllowUnauthenticatedIdentities: false # 根据需求决定是否允许未认证用户访问 CognitoIdentityProviders: - ClientId: !Ref MyCognitoUserPoolClient # 关联上面创建的应用客户端 ProviderName: !GetAtt MyExistingUserPool.ProviderName # 自动获取用户池的提供商名称 # 关联身份池与IAM角色 MyCognitoIdentityPoolRoleAttachment: Type: AWS::Cognito::IdentityPoolRoleAttachment Properties: IdentityPoolId: !Ref MyCognitoIdentityPool Roles: authenticated: !GetAtt AuthenticatedUserRole.Arn # 认证用户的角色ARN # unauthenticated: !GetAtt UnauthenticatedUserRole.Arn # 如果允许未认证用户,取消注释 # 示例认证用户角色(根据你的业务需求调整权限) AuthenticatedUserRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Federated: cognito-identity.amazonaws.com Action: sts:AssumeRoleWithWebIdentity Condition: StringEquals: cognito-identity.amazonaws.com:aud: !Ref MyCognitoIdentityPool ForAnyValue:StringLike: cognito-identity.amazonaws.com:amr: authenticated Policies: - PolicyName: AuthenticatedUserAccess PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "execute-api:Invoke" # 允许访问你的API网关 Resource: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyExistingAPIGateway}/*" # 替换成你的API网关资源名称
整合提示
把以上所有资源块添加到你现有的CloudFormation/SAM模板中,确保所有引用的资源名称(比如MyExistingUserPool、MyExistingAPIGateway)和你模板中的实际资源名称完全一致。如果使用SAM,这些CloudFormation资源可以直接和SAM资源(比如AWS::Serverless::Api)兼容,不需要额外修改。
内容的提问来源于stack exchange,提问作者Jeff

