Search code examples
amazon-web-servicesamazon-ec2amazon-cognitoaws-application-load-balancer

AWS Gov Cloud application load balancer authenticate rule with Cognito


In AWS' commercial cloud (us-west-2), I can create an ALB listener rule on my HTTPS (443) listener to first authenticate to a Cognito user pool (with OIDC integration Azure AD) and then forward to an Ec2 instance after successful authentication.

I try the same things in gov cloud (gov-west-1), and there is no option to Authenticate in a Load Balance listener rule with Cognito, only pure OIDC authentication.

Does this feature exist in Gov cloud?

I'm specifically discussing the attached "insert rule" UI shown in the image. In my gov cloud account (gov-west-2), "Amazon Cognito" is not an option in the "1. Authentucate" dropdown. The only option that exists is "OIDC"

enter image description here


Solution

  • This feature is sadly not yet available in GovCloud (see this doc on govcloud-differences), but you can get around this by setting up an OIDC auth action directed to your Cognito User Pool (which is able to act as a standard OIDC provider).

    This auth action requires you to provide OIDC endpoints which are described for AWS Cognito at the following docs page: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html

    This does require you to set up a User Pool App Client, configured with a Client Secret, as well as a User Pool Domain.

    Lastly, make sure to configure your CallbackURLs for the Cognito Client to allow redirects back to the /oauth2/idpresponse endpoint on your Load Balancer; e.g. for a Load Balancer at <DNS>, use CallbackURL: https://DNS/oauth2/idpresponse.

    When you configure the auth action, you will need to supply the following details:

    • Authenticate: OIDC
    • Issuer: https://cognito-idp.us-gov-west-1.amazonaws.com/us-gov-west-1_abc123
    • Authorization endpoint: https://my-cognito-domain.auth-fips.us-gov-west-1.amazoncognito.com/oauth2/authorize
    • Token endpoint: https://my-cognito-domain.auth-fips.us-gov-west-1.amazoncognito.com/oauth2/token
    • User info endpoint: https://my-cognito-domain.auth-fips.us-gov-west-1.amazoncognito.com/oauth2/userInfo
    • Client ID: abcdef123456
    • Client secret: hunter7

    Sample CloudFormation snippet follows:

    Parameters:
      SessionTimeout:
        Description: The maximum duration of the authentication session, in seconds.
        Type: Number
        Default: 604800  # One day
        MinValue: 60
        MaxValue: 604800
      CognitoClientID:
        Description: Client ID from pre-configured cognito environment
        Type: String
        NoEcho: true
      CognitoClientSecret:
        Description: Client Secret from pre-configured cognito environment
        Type: String
        NoEcho: true
      CognitoProviderUrl:
        Description: Provider URL from pre-configured cognito environment
        Type: String
      CognitoDomainName:
        Description: Domain Name from pre-configured cognito environment
        Type: String
      TargetGroupArn:
        Description: ARN of the Target Group for forwarding traffic
        Type: String
    
    Conditions:
      IsGovCloud: !Not [!Equals ['aws', !Ref AWS::Partition]]
    
    Resources:
      AuthenticatedListenerRule:
        Type: AWS::ElasticLoadBalancingV2::ListenerRule
        Properties:
          Actions:
            - Type: authenticate-oidc
              Order: 1
              AuthenticateOidcConfig:
                ClientId: !Ref CognitoClientID
                ClientSecret: !Ref CognitoClientSecret
                Issuer: !Ref CognitoProviderUrl
                UserInfoEndpoint:
                  Fn::Sub:
                    - https://${CognitoDomainName}.${AuthSuffix}.${AWS::Region}.amazoncognito.com/oauth2/userInfo
                    - AuthSuffix: !If [IsGovCloud, "auth-fips", "auth"]
                AuthorizationEndpoint:
                  Fn::Sub:
                    - https://${CognitoDomainName}.${AuthSuffix}.${AWS::Region}.amazoncognito.com/oauth2/authorize
                    - AuthSuffix: !If [IsGovCloud, "auth-fips", "auth"]
                TokenEndpoint:
                  Fn::Sub:
                    - https://${CognitoDomainName}.${AuthSuffix}.${AWS::Region}.amazoncognito.com/oauth2/token
                    - AuthSuffix: !If [IsGovCloud, "auth-fips", "auth"]
                OnUnauthenticatedRequest: authenticate
                Scope: openid
                SessionTimeout: !Ref SessionTimeout
            - Type: forward
              Order: 2
              TargetGroupArn:
                Ref: TargetGroup
    

    Best of luck and let's hope for expanded GovCloud features soon