Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I setup AWS Cognito User Pool Identity Providers with Cloudformation?

I want to setup a cognito user pool and configure my google identity provider automatically with a cloudformation yml file.

I checked all the documentation but could not find anything even close to doing this. Any idea on how to do it?

enter image description here

like image 955
sigmaxf Avatar asked Mar 20 '18 23:03

sigmaxf


People also ask

Can Cognito be an IdP?

However, a Cognito user pool is its own IdP. If an identity pool is configured correctly, it can use the app's user pools as an IdP. This way, users authenticate via user pools and are assigned IAM roles via identity pools.

What is the difference between Cognito user pool and identity pool?

Short description. User pools are for authentication (identity verification). With a user pool, your app users can sign in through the user pool or federate through a third-party identity provider (IdP). Identity pools are for authorization (access control).


4 Answers

UserPoolIdentityProvider was added in Oct 2019, official docs.

Your CloudFormation would then look something like

CognitoUserPoolIdentityProvider:
  Type: AWS::Cognito::UserPoolIdentityProvider
  Properties: 
    ProviderName: Google
    AttributeMapping:
      email: emailAddress
    ProviderDetails:
      client_id: <yourclientid>.apps.googleusercontent.com
      client_secret: <yourclientsecret>
      authorize_scopes: email openid
    ProviderType: Google
    UserPoolId: 
      Ref: CognitoUserPool
like image 136
vgaltes Avatar answered Oct 24 '22 20:10

vgaltes


It seems a lot of Cognito details are not supported within Cloudformation as of right now, but there are ways to achieve what you want after the stack spins up, e.g. using Lambdas.

See the following answers:

Cannot set a property of cognito userpool client via cloudformation

Cloudformation Cognito - how to setup App Client Settings, Domain, and Federated Identities via SAM template

like image 30
Jens Roland Avatar answered Oct 24 '22 18:10

Jens Roland


You can achieve this using Lambda function as custom Cloudformation resources. I have made custom resources to allow creation of user pool domain, client settings and Identity providers on this repo

You will have somethings like this for creating identity provider, for example Facebook

FacebookIdp:
  Type: 'Custom::${self:service}-${self:provider.stage}-CUPIdentityProvider'
  DependsOn:
    - CFNSendResponseLambdaFunction
    - CUPIdentityProviderLambdaFunction
  Properties:
    ServiceToken:
      Fn::GetAtt: [CUPIdentityProviderLambdaFunction, Arn]
    UserPoolId:
      Ref: AppUserPool
    ProviderName: Facebook
    ProviderType: Facebook
    Client_id: 'YourFacebookAppID'
    Client_secret: 'YourFacebookAppSecert'
    Authorize_scopes: 'public_profile,email'

And then enable that identity provider on the user pool client settings

AppUserPoolClientSettings:
  Type: 'Custom::${self:service}-${self:provider.stage}-CUPClientSettings'
  DependsOn:
    - CFNSendResponseLambdaFunction
    - CUPClientSettingsLambdaFunction
    - FacebookIdp
  Properties:
    ServiceToken:
      Fn::GetAtt: [ CUPClientSettingsLambdaFunction, Arn]
    UserPoolId: 
      Ref: AppUserPool
    UserPoolClientId: 
      Ref: AppUserPoolClient
    SupportedIdentityProviders:
      - COGNITO
      - Facebook
    CallbackURL: 'https://www.yourdomain.com/callback' ##Replace this with your app callback url
    LogoutURL: 'https://www.yourdomain.com/logout' ##Replace this with your app logout url
    AllowedOAuthFlowsUserPoolClient: true
    AllowedOAuthFlows:
      - code
    AllowedOAuthScopes:
      - openid

Note that this repo is built using Serverless framework, if you wish to build this with pure cloudformation stacks, use the code on file CUPIdentityProvider.js to make your own custom resource.

like image 2
Qassim Al-Shakhoori Avatar answered Oct 24 '22 18:10

Qassim Al-Shakhoori


Using a generic custom resource provider, you can create all the resource CFN doesn't support.

The example given here specifically creates and configures Cognito for Google SAML auth.

It should be easy enough to change it to use Google oAuth instead of SAML by changing the parameters passed to the custom resource handler, for example.

  UserPoolIdentityProvider:
    Type: 'Custom::CognitoUserPoolIdentityProvider'
    Condition: HasMetadata
    DependsOn: UserPool
    Properties:
      ServiceToken: !Sub '${CustomResourceLambdaArn}'
      AgentService: cognito-idp
      AgentType: client
      # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.create_user_pool_domain
      AgentCreateMethod: create_identity_provider
      AgentUpdateMethod: update_identity_provider
      AgentDeleteMethod: delete_identity_provider
      AgentResourceId: ProviderName
      AgentCreateArgs:
        UserPoolId: !Sub '${UserPool}'
        ProviderName: google-provider
        AttributeMapping:
          email: emailAddress
        ProviderDetails:
          google_app_id: some_value
          google_app_secret: some_value
          google_authorize_scope: some_value
        ProviderType: Google
      AgentUpdateArgs:
        UserPoolId: !Sub '${UserPool}'
        ProviderName: google-provider
        AttributeMapping:
          email: emailAddress
        ProviderDetails:
          google_app_id: some_value
          google_app_secret: some_value
          google_authorize_scope: some_value
        ProviderType: Google
      AgentDeleteArgs:
        UserPoolId: !Sub '${UserPool}'
        ProviderName: google-provider

you'll need to create a test provider in the console to get the correct names for parameters under ProviderDetails, namely Google app ID, App secret and Authorize scope. Also the AttributeMapping might need to be set to something else.

like image 1
ab77 Avatar answered Oct 24 '22 18:10

ab77