Securing Amazon Elastic Container Service applications using Application Load Balancer and Amazon Cognito

大数据
数据分析
容器
海外精选
海外精选的内容汇集了全球优质的亚马逊云科技相关技术内容。同时,内容中提到的“AWS” 是 “Amazon Web Services” 的缩写,在此网站不作为商标展示。
0
0
{"value":"### **Introduction**\nDesigning and maintaining secure user management, authentication and other related features for applications is not an easy task. [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway) takes care of this work, which allows developers to focus on building the core business logic of the application.\n\nAmazon Cognito provides user management, authentication, and authorization for applications where users can log in in directly or through their pre-existing social or corporate credentials.\n\n[Amazon Elastic Containers Service](https://docs.aws.amazon.com/ecs/?id=docs_gateway) (Amazon ECS) is a fully managed container orchestration service that makes it easy for customers to deploy, manage, and scale their container-based applications. When building using Amazon ECS, it is common to use Application Load Balancer (ALB) for application high availability and other features like SSL/TLS offloading, host based routing, and other application-aware traffic handling.\n\nAnother benefit of using the ALB with [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) is that the ALB has in-built support for Amazon Cognito.\n\nWhen setting up the ALB, you can chose if you want incoming user traffic to be redirected to Amazon Cognito for authentication. By building secure containerized applications using Amazon ECS, and using ALB and its Amazon Cognito integration, you get the benefits of the ease of container orchestration and user authentication and authorization.\n\n### **Flow of how Application Load Balancer authenticates users using Amazon Cognito**\nFor an application fronted by ALB that integrates with Amazon Cognito and has been set up to authenticate users, the following stepwise flow describes what happens when a user attempts to access the application.\n\nFor more information, see the example built by the [Amazon Web Services Elastic Load Balancing Demos](https://www.exampleloadbalancer.com/auth_demo.html).\n\n![image.png](https://dev-media.amazoncloud.cn/46dfa8b650254622996182ffe67aac07_image.png)\n\nYou need to understand what the ALB is doing to secure user access with [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway):\n\n1. A user sends a request to the application fronted by the ALB, which has a set of rules that it evaluates for all traffic to determine what action to carry out. The rule (such as the path-based rule saying all traffic for/```login```) when matched triggers the authentication action on the ALB. The ALB then inspects the user’s HTTP payload for an authentication cookie.\n2. Because this is the user’s first visit, this cookie isn’t present. The ALB doesn’t see any cookie and redirects the user to the configured Amazon Cognito’s authorization endpoint.\n3. The user is presented with an authentication page from Amazon Cognito, where the user inputs their credentials. Amazon Cognito redirects the user back to the ALB and passes an authorization code to the user in the redirect URL.\n4. The load balancer takes this authorization code and makes a request to Amazon Cognito’s token endpoint.\n5. Amazon Cognito validates the authorization code and presents the ALB with an ID and access token.\n6. The ALB forwards the access token to Amazon Cognito’s user info endpoint.\n7. Amazon Cognito’s user information endpoint presents the ALB with user claims.\n8. The ALB redirects the user who is trying to access the application (step 1) to the same URL while inserting the authentication cookie in the redirect response.\n9. The user makes the request to the ALB with the cookie and the ALB validates it and forwards the request to the ALB’s target. The ALB inserts information (such as user claims, access token, and the subject field) into a set of ```X-AMZN-OIDC-*``` HTTP headers to the target.\n10. The target generates a response and forwards to the ALB.\n11. The ALB sends the response to the authenticated user.\n\nWhen the user makes subsequent requests for HTTP request and response, the flow will go through steps 9–11. If the user makes a new request without the authentication cookie, it goes through steps 1–11.\n\nFor more information, see the [authentication](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#authentication-flow) flow between the ALB and Amazon Cognito.\n\n### **Solution overview**\nYou will use a PHP application built for demonstration purpose. The application is published and verified in the public docker hub. We use and configure Amazon Route 53 for Domain Name Service (DNS) handling and [Amazon Web Services Certificate Manager](https://docs.aws.amazon.com/acm/?id=docs_gateway) (ACM) to provision Transport Layer Security (TLS) Certificates for usage.\n\nAmazon Cognito handles the Authentication flows and Amazon ECS handles the container scheduling and orchestration.\n\nThe following solution architecture diagram presents an overview of the solution.\n\n![image.png](https://dev-media.amazoncloud.cn/1abf277f9f6746ef8234a2c791c5642b_image.png)\n\n#### **Prerequisites**\nTo complete this tutorial you need the following tools, which can be installed with the links:\n\n- [aws cliv2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html): The Amazon Web Services [Command Line Interface](https://docs.aws.amazon.com/cli/?id=docs_gateway) (Amazon Web Services CLI) is an open source tool that allows you interact with Amazon Web Services services using commands in your command-line shell.\n- [ecs-cli](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI.html): The [Amazon Elastic Container Service](https://docs.aws.amazon.com/ecs/?id=docs_gateway) (Amazon ECS) CLI provides high-level commands to simplify creating, updating, and monitoring tasks and clusters from a local development environment.\n\n#### **Environment**\nIn this post, I used the [Amazon Web Services Cloud9](https://docs.aws.amazon.com/cloud9/?id=docs_gateway) as an Integrated Development Environment (IDE) to configure the settings in this tutorial. You can use Amazon Web Services Cloud9 or your own IDE. The commands used were tested using Amazon Linux 2 running in the Amazon Cloud9 environment.\n\nFollow the steps [linked](https://ecsworkshop.com/start_the_workshop/workspace/) to [install and configure](https://ecsworkshop.com/microservices/software/) Amazon Cloud9:\n\nCreate a workspace to deploy this solution, which includes creating an [Amazon Web Services Identity and Access Management](https://docs.aws.amazon.com/iam/?id=docs_gateway) (IAM) role that will be attached to the workspace instance.\n\n#### **Launch the base infrastructure platform that the resources reside in**\nThe [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) needs to be launched into a Virtual Private Cloud (VPC) infrastructure. To create this infrastructure, you use an [Amazon Web Services CloudFormation](https://aws.amazon.com/cloudformation/) template that automates the creation of the platform.\n\nDownload the [zip file](https://docs.aws.amazon.com/codebuild/latest/userguide/samples/samples.zip) that contains an Amazon Web Services CloudFormation yaml file: ```codebuild-vpc-cfn.yaml```.\n\nOnce deployed, the following resources are created into your Amazon Web Services account: a Virtual Private Cloud (VPC), an internet gateway, two public subnets, two private subnets, two Network Address Translation (NAT) Gateways, and one security group.\n\nTo launch the stack, follow these steps:\n\n- Sign in to the [Amazon Web Services Management Console](https://console.aws.amazon.com/).\n- In your Region of choice, you will see the Region list in the top right-hand corner.\n- Search for the [Amazon Web Services CloudFormation](https://docs.aws.amazon.com/cloudformation/?id=docs_gateway) service in the Console search bar.\n- Choose **Create Stack** and select **with new resources (standard)**.\n- To **specify template**, choose **upload a template file**.\n- Upload the previously downloaded: ```codebuild-vpc-cfn.yaml``` file.\n- To create the stack and configure stack options, choose **Next**.\n- Enter **ecsplatform** for stack name and **ecsplatform** for ```EnvironmentName```. Choose **Next**.\n- Leave the rest of the default settings and choose **Next**.\n- Choose **Create Stack**.\n- When CloudFormation has completed its deployment its the resources, the status is **CREATE_COMPLETE**.\n\nNext on your [Amazon Cloud9](https://docs.aws.amazon.com/cloud9/?id=docs_gateway) workspace terminal, set the below environment variables:\n\n```\nAUTH_ECS_REGION=eu-west-1 <-- Change to the region you used in your Cloudformation configuration\nAUTH_ECS_CLUSTER=ecsauth\nAUTH_ECS_VPC=$(aws cloudformation describe-stacks --stack-name ecsplatform --query \"Stacks[0].Outputs[?OutputKey=='VPC'].OutputValue\" --output text)\nAUTH_ECS_PUBLICSUBNET_1=$(aws cloudformation describe-stacks --stack-name ecsplatform --query \"Stacks[0].Outputs[?OutputKey=='PublicSubnet1'].OutputValue\" --output text)\nAUTH_ECS_PUBLICSUBNET_2=$(aws cloudformation describe-stacks --stack-name ecsplatform --query \"Stacks[0].Outputs[?OutputKey=='PublicSubnet2'].OutputValue\" --output text)\nAUTH_ECS_PRIVATESUBNET_1=$(aws cloudformation describe-stacks --stack-name ecsplatform --query \"Stacks[0].Outputs[?OutputKey=='PrivateSubnet1'].OutputValue\" --output text)\nAUTH_ECS_PRIVATESUBNET_2=$(aws cloudformation describe-stacks --stack-name ecsplatform --query \"Stacks[0].Outputs[?OutputKey=='PrivateSubnet2'].OutputValue\" --output text)\nAUTH_ECS_SG=$(aws cloudformation describe-stacks --stack-name ecsplatform --query \"Stacks[0].Outputs[?OutputKey=='NoIngressSecurityGroup'].OutputValue\" --output text)\nAUTH_ECS_DOMAIN=www.example.com <-- Change to a domain name you want to use for this solution for this solution\n```\n\nYou will set additional variables later, but these are enough to begin building your solution.\n\n#### **Configure the security group rules needed for web traffic access**\nWhen users access the ALB, the security group attached to it needs to allow ingress port 443 (https) traffic. In addition, when the ALB forwards the web traffic to the Amazon ECS tasks there needs to be a ingress rules attached to the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) container instances that allows ingress port 80 (http) traffic.\n\nYou can achieve this access with the following:\n\n```\naws ec2 authorize-security-group-ingress \\\n --group-id $AUTH_ECS_SG \\\n --protocol tcp \\\n --port 443 \\\n --cidr 0.0.0.0/0\n \naws ec2 authorize-security-group-ingress \\\n--group-id $AUTH_ECS_SG \\\n--protocol tcp \\\n--port 80 \\\n--cidr 0.0.0.0/0\n```\n\n#### **Create a public Application Load Balancer**\nAs described earlier, the ALB will receive and terminate all client requests to validate for authentication using [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway). The ALB also handles TLS offloading where the TLS certificates for the domain name will be deployed on it.\n\nTo create the ALB do the below:\n\n```\nAUTH_ECS_ALBARN=$(aws elbv2 create-load-balancer --name $AUTH_ECS_CLUSTER --subnets $AUTH_ECS_PUBLICSUBNET_1 $AUTH_ECS_PUBLICSUBNET_2 --security-groups $AUTH_ECS_SG --query 'LoadBalancers[0].LoadBalancerArn' --output text)\n\nAUTH_ECS_ALB_DNS=$(aws elbv2 describe-load-balancers --load-balancer-arns $AUTH_ECS_ALBARN --query 'LoadBalancers[0].DNSName' --output text)\n```\n\n#### **Configure a Domain Name System**\nClients will need a domain name that points to the ALB to type into their browsers.\n\nIn this post, the Domain Name System (DNS) name is registered using the DNS Resolution service, [Amazon Route 53](https://aws.amazon.com/route53/).\n\nYou can configure your domain name (such as [www.example.com](http://www.example.com/) where it‘s known as the record and placed in a Route 53-hosted zone.\n\n##### **Configure both the Route 53 hosted zone and record**\nIf you already have a ```Route53``` publicly hosted zone for the apex domain and this is the location where you plan to add the record, then you will set its host zone ID (```AUTH_ECS_R53HZ```). For more information, see the hosted [zone ID](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/SOA-NSrecords.html#NSrecords) documentation.\n\nThe first command line shown below demonstrates how to identify a hosted zone ID. You can substitute [*example.com*](http://example.com/) for your apex domain name. The other commands create a record that points to the ALB.\n\n```\nAUTH_ECS_R53HZ=$(aws route53 list-hosted-zones-by-name --dns-name example.com --query 'HostedZones[0].Id' --output text | grep -o '/hostedzone/.*' | cut -b 13-27) \n\ncat << EOF > dnsrecord.json\n{\n \"Comment\": \"CREATE a DNS record that points to the ALB\",\n \"Changes\": [\n {\n \"Action\": \"CREATE\",\n \"ResourceRecordSet\": {\n \"Name\": \"$AUTH_ECS_DOMAIN\",\n \"Type\": \"CNAME\",\n \"TTL\": 300,\n \"ResourceRecords\": [\n {\n \"Value\": \"$AUTH_ECS_ALB_DNS\"\n }\n ]\n }\n }\n ]\n}\nEOF \naws route53 change-resource-record-sets --hosted-zone-id $AUTH_ECS_R53HZ --change-batch file://dnsrecord.json\n```\n\n#### **Request a public certificate**\nTo ensure that web traffic sent by clients to the ALB is encrypted, integrate an ACM ([Amazon Web Services Certificate Manager](https://docs.aws.amazon.com/acm/?id=docs_gateway) Certificate into the ALB’s listener. This ensures that the ALB serves HTTPS traffic and communications from clients to ALB is encrypted. Public SSL/TLS certificates provisioned through Amazon Web Services Certificate Manager are [free](https://aws.amazon.com/certificate-manager/pricing/). You pay only for the Amazon Web Services resources you create to run your application.\n\n\n##### **Provision an ACM certificate**\n\n```\nAUTH_ECS_ACM_CERT_ARN=$(aws acm request-certificate \\\n --domain-name $AUTH_ECS_DOMAIN \\\n --validation-method DNS \\\n --region $AUTH_ECS_REGION \\\n --query 'CertificateArn' \\\n --output text)\n```\n\nWhen you create an SSL/TLS Certificate using ACM, it will try to confirm that you’re the owner of the domain name before fully provisioning the certificate for you to use. One method of confirmation is through DNS validation.\n\nThrough this method ACM creates two CNAME records that you must add in your Route53 hosted zone.\n\nTo add the ACM CNAME records in your Route53 hosted zones:\n\n```\ncat << EOF > acm_validate_cert_dns.json\n{\n \"Changes\":[\n {\n \"Action\": \"UPSERT\",\n \"ResourceRecordSet\":{\n \"Name\": \"$(aws acm describe-certificate --certificate-arn $AUTH_ECS_ACM_CERT_ARN --query 'Certificate.DomainValidationOptions[].ResourceRecord[].Name' --output text)\",\n \"Type\": \"CNAME\",\n \"TTL\": 300,\n \"ResourceRecords\": [\n {\n \"Value\": \"$(aws acm describe-certificate --certificate-arn $AUTH_ECS_ACM_CERT_ARN --query 'Certificate.DomainValidationOptions[].ResourceRecord[].Value' --output text)\"\n }\n ]\n }\n }\n ]\n }\nEOF\naws route53 change-resource-record-sets \\\n --hosted-zone-id $AUTH_ECS_R53HZ \\\n --change-batch file://acm_validate_cert_dns.json\n```\n\nIt takes some time before the certificate will change from ‘Pending Validation’ to ‘Success’.\n\nOnce the status shows ‘Issued’ on the [ACM console](https://console.aws.amazon.com/acm/) then you can use the certificate.\n\n##### **Create an HTTPS listener and listener rule on the ALB**\nNow that you’ve created the ALB. In addition, you’ve also created a certificate to configure the HTTPS listener to accept incoming HTTPS request from clients and to terminate them.\n\nYou integrate the certificate into the listener and add a default rule action on the ALB:\n\n```\ncat << EOF > listener-defaultaction.json\n[\n {\n \"Type\": \"redirect\",\n \"RedirectConfig\": {\n \"Protocol\": \"HTTPS\",\n \"Port\": \"443\",\n \"Host\": \"$AUTH_ECS_DOMAIN\",\n \"StatusCode\": \"HTTP_301\"\n }\n }\n]\nEOF\nAUTH_ECS_ALBLISTENER=$(aws elbv2 create-listener \\\n --load-balancer-arn $AUTH_ECS_ALBARN \\\n --protocol HTTPS \\\n --port 443 \\\n --certificates CertificateArn=$AUTH_ECS_ACM_CERT_ARN \\\n --ssl-policy ELBSecurityPolicy-2016-08 \\\n --default-actions file://listener-defaultaction.json \\\n --query 'Listeners[0].ListenerArn' \\\n --output text)\n```\n\n#### **Create an Amazon Cognito user pool**\nAs previously described, [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway) provides user management, authentication and authorization for applications where users can login in directly or through their pre-existing social/corporate credentials.\n\nCreate a user pool, which is a user directory in Amazon Cognito that helps clients to access the website. Clients sign in with their credentials before they get access to the site.\n\nTo fully configure Amazon Cognito for integration with the ALB, create a [user pool](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html), a user pool [application client](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html), and a [user pool domain](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-domain.html). The following steps show you how to accomplish these tasks.\n\n##### **Create an Amazon Cognito user pool**\n\n```\nAUTH_COGNITO_USER_POOL_ID=$(aws cognito-idp create-user-pool \\\n --pool-name ${AUTH_ECS_CLUSTER}_Pool \\\n --username-attributes email \\\n --username-configuration=CaseSensitive=false \\\n --region $AUTH_ECS_REGION \\\n --query 'UserPool.Id' \\\n --auto-verified-attributes email \\\n --output text)\n```\n\n##### **Create an Amazon Cognito user pool application client**\n\n```\nAUTH_COGNITO_USER_POOL_CLIENT_ID=$(aws cognito-idp create-user-pool-client \\\n --client-name ${AUTH_ECS_CLUSTER}_AppClient \\\n --user-pool-id $AUTH_COGNITO_USER_POOL_ID \\\n --generate-secret \\\n --allowed-o-auth-flows \"code\" \\\n --allowed-o-auth-scopes \"openid\" \\\n --callback-urls \"https://${AUTH_ECS_DOMAIN}/oauth2/idpresponse\" \\\n --supported-identity-providers \"COGNITO\" \\\n --allowed-o-auth-flows-user-pool-client \\\n --region $AUTH_ECS_REGION \\\n --query 'UserPoolClient.ClientId' \\\n --output text)\n```\n\n##### **Create an Amazon Cognito user pool domain**\n\n```\nAUTH_COGNITO_USER_POOL_ARN=$(aws cognito-idp describe-user-pool --user-pool-id $AUTH_COGNITO_USER_POOL_ID --query 'UserPool'.Arn --output text)\n\nAUTH_COGNITO_DOMAIN=(authecsblog$(whoami))\n\naws cognito-idp create-user-pool-domain \\\n --user-pool-id $AUTH_COGNITO_USER_POOL_ID \\\n --region $AUTH_ECS_REGION \\\n --domain $AUTH_COGNITO_DOMAIN\n```\n\n##### **Create and configure a target group for the ALB**\nCreate a target group for the ALB. The [target group](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/elbv2/create-target-group.html) is used to route requests to the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) tasks.\n\nWhen an ALB receives the HTTPS traffic from the web clients, it routes the requests to the target group (after authentication of the client has occurred) for a web response. (Amazon ECS tasks are registered to the target group in a later section “Configuring the ECS Service”).\n\nCreate an empty target group:\n\n```\nAUTH_ECS_ALBTG=$(aws elbv2 create-target-group \\\n --name ${AUTH_ECS_CLUSTER}-tg \\\n --protocol HTTP \\\n --port 80 \\\n --target-type instance \\\n --vpc-id $AUTH_ECS_VPC \\\n --query 'TargetGroups[0].TargetGroupArn' \\\n --output text)\n```\n\n##### **Host-based routing and an authentication rule on the ALB**\nThe ALB routes requests based on the host name in the HTTP host header.\n\nIt is possible to configure multiple domains that all point to a single ALB because the ALB can route requests based on the incoming host header and forward the requests to the right target group for handling.\n\nYou can configure an [authentication rule](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#configure-user-authentication) which tells the ALB what to do to the incoming requests. In this post, we want the requests to first be authenticated and, if successful, the request should get forwarded to the target group we created earlier.\n\n##### **Configure host-based routing and an authentication rule on the ALB**\n\n```\ncat << EOF > actions-authenticate.json\n [\n {\n \"Type\": \"authenticate-cognito\",\n \"AuthenticateCognitoConfig\": {\n \"UserPoolArn\": \"$AUTH_COGNITO_USER_POOL_ARN\",\n \"UserPoolClientId\":\n\"$AUTH_COGNITO_USER_POOL_CLIENT_ID\",\n \"UserPoolDomain\": \"$AUTH_COGNITO_DOMAIN\",\n \"SessionCookieName\": \"AWSELBAuthSessionCookie\",\n \"Scope\": \"openid\",\n \"OnUnauthenticatedRequest\": \"authenticate\"\n },\n \"Order\": 1\n },\n {\n \"Type\": \"forward\",\n \"TargetGroupArn\": \"$AUTH_ECS_ALBTG\",\n \"Order\": 2\n }\n ]\nEOF\n\ncat << EOF > conditions-hostrouting.json\n[\n {\n \"Field\": \"host-header\",\n \"HostHeaderConfig\": {\n \"Values\": [\"$AUTH_ECS_DOMAIN\"]\n }\n }\n]\nEOF\n\naws elbv2 create-rule \\\n --listener-arn $AUTH_ECS_ALBLISTENER \\\n --priority 20 \\\n --conditions file://conditions-hostrouting.json \\\n --actions file://actions-authenticate.json\n```\n\n#### **Amazon ECS configuration**\nThe ALB and [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway) are now configured for processing incoming requests and authentication.\n\nNext you will configure [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) to orchestrate and deploy running tasks to generate response for the client’s web request.\n\nAn Amazon ECS cluster is a logical grouping of tasks or services. Amazon ECS instances are part of the Amazon ECS infrastructure registered to a cluster that the Amazon ECS tasks run on.\n\nTwo ```t3.small``` Amazon ECS instances will be configured to run the tasks. Amazon ECS will run and maintain two tasks, which are configured based on parameters and settings contained in the task definition (a ```JSON``` text file).\n\nFor more information on Amazon ECS basics, constructs, and orchestration read the [Amazon ECS components](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/welcome-features.html) documentation.\n\n##### **Configure the Amazon ECS CLI**\n[Amazon ECS CLI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/welcome-features.html) is the tool that you’d use to configure and launch the Amazon ECS components.\n\nTo download Amazon ECS CLI, follow the following steps:\n\nAmazon ECS CLI needs a CLI profile, to proceed generate an access key ID, and access key using the [Amazon Web Services credentials documentation](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys).\n\nSet the ```$AWS_ACCESS_KEY_ID``` and ```$AWS_SECRET_ACCESS_KEY``` variables to the copied values generated by [Amazon Web Services IAM](https://docs.aws.amazon.com/iam/?id=docs_gateway).\n\n##### **Configure the Amazon ECS CLI for a CLI profile**\n\n```\necs-cli configure profile --profile-name profile_name --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY\n```\n\n##### **Create the Amazon ECS cluster**\nCreate the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) cluster, which consists of two ```t3.small``` instance types deployed in the VPC and residing in the two private subnets from earlier. For the instance-role, use the [Amazon Web Services IAM](https://docs.aws.amazon.com/iam/?id=docs_gateway) role created when configuring the [Amazon Web Services Cloud9](https://docs.aws.amazon.com/cloud9/?id=docs_gateway) environment workspace (```ecsworkshop-admin```).\n\nThe first command creates a keypair and the second command configures the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) cluster. The keypair is useful if you need to SSH into the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) instances for troubleshooting.\n\n##### **Configure the Amazon EC2 key pair and bring up the ECS cluster**\n\n```\naws ec2 create-key-pair \\\n --key-name $AUTH_ECS_CLUSTER \\\n --key-type rsa \\\n --query \"KeyMaterial\" \\\n --output text > $AUTH_ECS_CLUSTER.pem\n \necs-cli up --instance-role ecsworkshop-admin --cluster $AUTH_ECS_CLUSTER --vpc $AUTH_ECS_VPC --subnets $AUTH_ECS_PRIVATESUBNET_1,$AUTH_ECS_PRIVATESUBNET_2 --port 443 --region $AUTH_ECS_REGION --keypair $AUTH_ECS_CLUSTER --size 2 --instance-type t3.small --security-group $AUTH_ECS_SG --launch-type EC2\n```\n\nThe cluster creation will take some time, when fully deployed the [Amazon Web Services CloudFormation](https://docs.aws.amazon.com/cloudformation/?id=docs_gateway) stack status will output ‘Cluster creation succeeded’.\n\n##### **Configure the Amazon Web Services Region and ECS cluster name using the configure command:**\n\n```\necs-cli configure --region $AUTH_ECS_REGION --cluster $AUTH_ECS_CLUSTER --default-launch-type EC2 --config-name $AUTH_ECS_CLUSTER\n```\n\nThe ```EC2``` launch type, with [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) instances, is created and launched in your VPC. If you prefer not to manage the underlying instances hosting the tasks, then Fargate launch type is the option to use. [Fargate](https://aws.amazon.com/fargate/) is the serverless way to host your Amazon ECS workloads.\n\n##### **Create the ECS service**\n\nThe ```ecs-cli compose service``` up command will create the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) service and tasks from a Docker Compose file (```ecsauth-compose.yaml```) that you create. This service is configured to use the ALB that you created earlier. A task definition is created by the command.\n\nThe Docker Compose file contains the configuration settings that the Amazon ECS service is spun up with. This includes the Docker image to pull and use, the ports to expose on the Amazon ECS instance, and the Amazon ECS task for network forwarding. In this post, we configured it to use the Amazon Web Services published sample demo PHP application verified and published to [Docker Hub](https://hub.docker.com/r/amazon/amazon-ecs-sample). Also, the Transmission Control Protocol (TCP) ```port 80``` will be opened on the [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) instance and traffic received on this port will be forwarded to the task on TCP ```port 80```).\n\n##### **Configuring the ECS service**\n\n```\ncat << EOF > ecsauth-compose.yml\nversion: '2'\nservices:\n web:\n image: amazon/amazon-ecs-sample\n ports:\n - \"80:80\"\nEOF\necs-cli compose --project-name ${AUTH_ECS_CLUSTER}service --file ecsauth-compose.yml service up --target-group-arn $AUTH_ECS_ALBTG --container-name web --container-port 80 --role ecsServiceRole\necs-cli compose --project-name ${AUTH_ECS_CLUSTER}service --file ecsauth-compose.yml service scale 2\n```\n\n##### **Testing the solution end to end**\n\nWe now the have working components of the solution. To test the solution end to end, you can navigate to the https site of the domain name used in your browser (such as [https://www.example.com](https://www.example.com/).\n\n```\necho $AUTH_ECS_DOMAIN\n```\n\nThe sequence of events that follows is as we described in the flow of how the ALB authenticates users using [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway) (section “Flow of how Application Load Balancer authenticates users using Amazon Cognito”).\n\nAfter redirection by the ALB to the Amazon Cognito configured domain’s login page (a hosted UI by Amazon Cognito), enter input your credentials.\n\nSince this is the first time the page is accessed we will sign up as a new user. Amazon Cognito stores this information in the user pool. If you navigate to the Amazon Cognito user pool console after, you’ll see this new user.\n\n![image.png](https://dev-media.amazoncloud.cn/9c20b77ea29d48ca97b15ca3444f24c6_image.png)\n\nAfter signing in to the ALB, it redirects you to the landing page of the sample demonstration PHP application, which is shown in the diagram below.\n\n![image.png](https://dev-media.amazoncloud.cn/9312d6ba440a4662b85d364643abeeaf_image.png)\n\n##### **User claims encoding and security**\nIn this post, we configured the target group to use HTTP, because the ALB has handled the TLS offloading. However, for enhanced security, you should restrict the traffic getting to the [Amazon ECS instances](https://docs.aws.amazon.com/ecs/?id=docs_gateway) to only the load balancer using the security group.\n\nAfter the load balancer authenticates a user successfully, it passes the claims of the user to the target. If you inspect traffic forwarded to the sample demonstration application through custom HTTP header logging in your access logs, you can see three HTTP headers. These headers contain information about the user claims and is signed by the ALB with a signature and algorithm that you can verify.\n\nThe three HTTP headers [include](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#user-claims-encoding) the following:\n\n```\nx-amzn-oidc-accesstoken\n```\n\nThe access token from the token endpoint, in plain text.\n\n```\nx-amzn-oidc-identity\n```\n\nThe subject field (sub) from the user info endpoint, in plain text.\n\n```\nx-amzn-oidc-data\n```\n\nThe user claims, in JSON web tokens (JWT) format.\n\nFrom information encoded in the ```x-amzn-oidc-data```, it is possible to extract information about the user.\n\nThe following is an example Python 3.x application that can decode the payload portion of the ```x-amzn-oidc-data``` to reveal the user claims passed by [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway).\n\n```\nimport jwt\nimport requests\nimport base64\nimport json\n\n# Step 1: Get the key id from JWT headers (the kid field)\n;\nencoded_jwt = headers.dict['x-amzn-oidc-data']\njwt_headers = encoded_jwt.split('.')[0]\ndecoded_jwt_headers = base64.b64decode(jwt_headers)\ndecoded_jwt_headers = decoded_jwt_headers.decode(\"utf-8\")\ndecoded_json = json.loads(decoded_jwt_headers)\nkid = decoded_json['kid']\n\n# Step 2: Get the public key from regional endpoint\nurl = 'https://public-keys.auth.elb.' + region + '.amazonaws.com/' + kidreq = requests.get(url)\npub_key = req.text\n\n# Step 3: Get the payload\npayload = jwt.decode(encoded_jwt, pub_key, algorithms=['ES256'])\n```\n\n### **Cleanup**\nNow that you are done building the solution and testing it to clean up all the resources you can run the following commands:\n\n```\naws elbv2 delete-load-balancer \\\n --load-balancer-arn $AUTH_ECS_ALBARN\n\naws ecs delete-service --cluster $AUTH_ECS_CLUSTER --service ${AUTH_ECS_CLUSTER}service –force\n\ncontainerinstance1=$(aws ecs list-container-instances --cluster $AUTH_ECS_CLUSTER --query 'containerInstanceArns[0]' --output text)\ncontainerinstance2=$(aws ecs list-container-instances –cluster\n$AUTH_ECS_CLUSTER --query 'containerInstanceArns[1]' --output text)\n\naws ecs deregister-container-instance \\\n --cluster $AUTH_ECS_CLUSTER \\\n --container-instance $containerinstance1 \\\n --force\n\naws ecs deregister-container-instance \\\n --cluster $AUTH_ECS_CLUSTER \\\n --container-instance $containerinstance2 \\\n --force\n\naws ecs delete-cluster --cluster $AUTH_ECS_CLUSTER\n\naws ecs deregister-task-definition --task-definition ${AUTH_ECS_CLUSTER}service:1\naws acm delete-certificate --certificate-arn $AUTH_ECS_ACM_CERT_ARN\naws route53 delete-hosted-zone --id $AUTH_ECS_R53HZ\n\naws cognito-idp delete-user-pool-domain \\\n --user-pool-id $AUTH_COGNITO_USER_POOL_ID \\\n --domain $AUTH_COGNITO_DOMAIN\n\naws cognito-idp delete-user-pool --user-pool-id $AUTH_COGNITO_USER_POOL_ID\n\naws elbv2 delete-target-group \\\n --target-group-arn $AUTH_ECS_ALBTG\n \naws cloudformation delete-stack \\\n --stack-name amazon-ecs-cli-setup-$AUTH_ECS_CLUSTER\n \naws cloudformation delete-stack \\\n --stack-name ecsplatform\n \naws ec2 delete-key-pair --key-name $AUTH_ECS_CLUSTER\n```\n\n### **Conclusion**\n\nIn this post, we showed you how to authenticate users accessing your containerized application without writing authentication code, using the ALB’s inbuilt integration with [Amazon Cognito](https://docs.aws.amazon.com/cognito/?id=docs_gateway). Maintaining and securing user management and authentication is offloaded from the application, which allows you to focus on building core business logic into the application. You don’t need to worry about platform tasks for managing, scheduling, and scaling containers for the web traffic because [Amazon ECS](https://docs.aws.amazon.com/ecs/?id=docs_gateway) handles all of that.\n\n![image.png](https://dev-media.amazoncloud.cn/1265d526bce14616b441ef6fbbdad417_image.png)\n\n**Chiedu Eluehike**\n\nan interest in poker.\n\nChiedu is an Enterprise Solutions Architect at Amazon Web Services currently based out of Sydney, Australia. In his role, he helps customers achieve their business objectives and uncover opportunities for value using Cloud Solutions. He is CCIE#48238. Outside of work, he enjoys watching and playing soccer, listening to podcasts, trying new food in restaurants, mindfulness meditation, and has taken","render":"<h3><a id=\"Introduction_0\"></a><strong>Introduction</strong></h3>\n<p>Designing and maintaining secure user management, authentication and other related features for applications is not an easy task. <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a> takes care of this work, which allows developers to focus on building the core business logic of the application.</p>\n<p>Amazon Cognito provides user management, authentication, and authorization for applications where users can log in in directly or through their pre-existing social or corporate credentials.</p>\n<p><a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon Elastic Containers Service</a> (Amazon ECS) is a fully managed container orchestration service that makes it easy for customers to deploy, manage, and scale their container-based applications. When building using Amazon ECS, it is common to use Application Load Balancer (ALB) for application high availability and other features like SSL/TLS offloading, host based routing, and other application-aware traffic handling.</p>\n<p>Another benefit of using the ALB with <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> is that the ALB has in-built support for Amazon Cognito.</p>\n<p>When setting up the ALB, you can chose if you want incoming user traffic to be redirected to Amazon Cognito for authentication. By building secure containerized applications using Amazon ECS, and using ALB and its Amazon Cognito integration, you get the benefits of the ease of container orchestration and user authentication and authorization.</p>\n<h3><a id=\"Flow_of_how_Application_Load_Balancer_authenticates_users_using_Amazon_Cognito_11\"></a><strong>Flow of how Application Load Balancer authenticates users using Amazon Cognito</strong></h3>\n<p>For an application fronted by ALB that integrates with Amazon Cognito and has been set up to authenticate users, the following stepwise flow describes what happens when a user attempts to access the application.</p>\n<p>For more information, see the example built by the <a href=\"https://www.exampleloadbalancer.com/auth_demo.html\" target=\"_blank\">Amazon Web Services Elastic Load Balancing Demos</a>.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/46dfa8b650254622996182ffe67aac07_image.png\" alt=\"image.png\" /></p>\n<p>You need to understand what the ALB is doing to secure user access with <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a>:</p>\n<ol>\n<li>A user sends a request to the application fronted by the ALB, which has a set of rules that it evaluates for all traffic to determine what action to carry out. The rule (such as the path-based rule saying all traffic for/<code>login</code>) when matched triggers the authentication action on the ALB. The ALB then inspects the user’s HTTP payload for an authentication cookie.</li>\n<li>Because this is the user’s first visit, this cookie isn’t present. The ALB doesn’t see any cookie and redirects the user to the configured Amazon Cognito’s authorization endpoint.</li>\n<li>The user is presented with an authentication page from Amazon Cognito, where the user inputs their credentials. Amazon Cognito redirects the user back to the ALB and passes an authorization code to the user in the redirect URL.</li>\n<li>The load balancer takes this authorization code and makes a request to Amazon Cognito’s token endpoint.</li>\n<li>Amazon Cognito validates the authorization code and presents the ALB with an ID and access token.</li>\n<li>The ALB forwards the access token to Amazon Cognito’s user info endpoint.</li>\n<li>Amazon Cognito’s user information endpoint presents the ALB with user claims.</li>\n<li>The ALB redirects the user who is trying to access the application (step 1) to the same URL while inserting the authentication cookie in the redirect response.</li>\n<li>The user makes the request to the ALB with the cookie and the ALB validates it and forwards the request to the ALB’s target. The ALB inserts information (such as user claims, access token, and the subject field) into a set of <code>X-AMZN-OIDC-*</code> HTTP headers to the target.</li>\n<li>The target generates a response and forwards to the ALB.</li>\n<li>The ALB sends the response to the authenticated user.</li>\n</ol>\n<p>When the user makes subsequent requests for HTTP request and response, the flow will go through steps 9–11. If the user makes a new request without the authentication cookie, it goes through steps 1–11.</p>\n<p>For more information, see the <a href=\"https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#authentication-flow\" target=\"_blank\">authentication</a> flow between the ALB and Amazon Cognito.</p>\n<h3><a id=\"Solution_overview_36\"></a><strong>Solution overview</strong></h3>\n<p>You will use a PHP application built for demonstration purpose. The application is published and verified in the public docker hub. We use and configure Amazon Route 53 for Domain Name Service (DNS) handling and <a href=\"https://docs.aws.amazon.com/acm/?id=docs_gateway\" target=\"_blank\">Amazon Web Services Certificate Manager</a> (ACM) to provision Transport Layer Security (TLS) Certificates for usage.</p>\n<p>Amazon Cognito handles the Authentication flows and Amazon ECS handles the container scheduling and orchestration.</p>\n<p>The following solution architecture diagram presents an overview of the solution.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/1abf277f9f6746ef8234a2c791c5642b_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"Prerequisites_45\"></a><strong>Prerequisites</strong></h4>\n<p>To complete this tutorial you need the following tools, which can be installed with the links:</p>\n<ul>\n<li><a href=\"https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html\" target=\"_blank\">aws cliv2</a>: The Amazon Web Services <a href=\"https://docs.aws.amazon.com/cli/?id=docs_gateway\" target=\"_blank\">Command Line Interface</a> (Amazon Web Services CLI) is an open source tool that allows you interact with Amazon Web Services services using commands in your command-line shell.</li>\n<li><a href=\"https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI.html\" target=\"_blank\">ecs-cli</a>: The <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon Elastic Container Service</a> (Amazon ECS) CLI provides high-level commands to simplify creating, updating, and monitoring tasks and clusters from a local development environment.</li>\n</ul>\n<h4><a id=\"Environment_51\"></a><strong>Environment</strong></h4>\n<p>In this post, I used the <a href=\"https://docs.aws.amazon.com/cloud9/?id=docs_gateway\" target=\"_blank\">Amazon Web Services Cloud9</a> as an Integrated Development Environment (IDE) to configure the settings in this tutorial. You can use Amazon Web Services Cloud9 or your own IDE. The commands used were tested using Amazon Linux 2 running in the Amazon Cloud9 environment.</p>\n<p>Follow the steps <a href=\"https://ecsworkshop.com/start_the_workshop/workspace/\" target=\"_blank\">linked</a> to <a href=\"https://ecsworkshop.com/microservices/software/\" target=\"_blank\">install and configure</a> Amazon Cloud9:</p>\n<p>Create a workspace to deploy this solution, which includes creating an <a href=\"https://docs.aws.amazon.com/iam/?id=docs_gateway\" target=\"_blank\">Amazon Web Services Identity and Access Management</a> (IAM) role that will be attached to the workspace instance.</p>\n<h4><a id=\"Launch_the_base_infrastructure_platform_that_the_resources_reside_in_58\"></a><strong>Launch the base infrastructure platform that the resources reside in</strong></h4>\n<p>The <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> needs to be launched into a Virtual Private Cloud (VPC) infrastructure. To create this infrastructure, you use an <a href=\"https://aws.amazon.com/cloudformation/\" target=\"_blank\">Amazon Web Services CloudFormation</a> template that automates the creation of the platform.</p>\n<p>Download the <a href=\"https://docs.aws.amazon.com/codebuild/latest/userguide/samples/samples.zip\" target=\"_blank\">zip file</a> that contains an Amazon Web Services CloudFormation yaml file: <code>codebuild-vpc-cfn.yaml</code>.</p>\n<p>Once deployed, the following resources are created into your Amazon Web Services account: a Virtual Private Cloud (VPC), an internet gateway, two public subnets, two private subnets, two Network Address Translation (NAT) Gateways, and one security group.</p>\n<p>To launch the stack, follow these steps:</p>\n<ul>\n<li>Sign in to the <a href=\"https://console.aws.amazon.com/\" target=\"_blank\">Amazon Web Services Management Console</a>.</li>\n<li>In your Region of choice, you will see the Region list in the top right-hand corner.</li>\n<li>Search for the <a href=\"https://docs.aws.amazon.com/cloudformation/?id=docs_gateway\" target=\"_blank\">Amazon Web Services CloudFormation</a> service in the Console search bar.</li>\n<li>Choose <strong>Create Stack</strong> and select <strong>with new resources (standard)</strong>.</li>\n<li>To <strong>specify template</strong>, choose <strong>upload a template file</strong>.</li>\n<li>Upload the previously downloaded: <code>codebuild-vpc-cfn.yaml</code> file.</li>\n<li>To create the stack and configure stack options, choose <strong>Next</strong>.</li>\n<li>Enter <strong>ecsplatform</strong> for stack name and <strong>ecsplatform</strong> for <code>EnvironmentName</code>. Choose <strong>Next</strong>.</li>\n<li>Leave the rest of the default settings and choose <strong>Next</strong>.</li>\n<li>Choose <strong>Create Stack</strong>.</li>\n<li>When CloudFormation has completed its deployment its the resources, the status is <strong>CREATE_COMPLETE</strong>.</li>\n</ul>\n<p>Next on your <a href=\"https://docs.aws.amazon.com/cloud9/?id=docs_gateway\" target=\"_blank\">Amazon Cloud9</a> workspace terminal, set the below environment variables:</p>\n<pre><code class=\"lang-\">AUTH_ECS_REGION=eu-west-1 &lt;-- Change to the region you used in your Cloudformation configuration\nAUTH_ECS_CLUSTER=ecsauth\nAUTH_ECS_VPC=$(aws cloudformation describe-stacks --stack-name ecsplatform --query &quot;Stacks[0].Outputs[?OutputKey=='VPC'].OutputValue&quot; --output text)\nAUTH_ECS_PUBLICSUBNET_1=$(aws cloudformation describe-stacks --stack-name ecsplatform --query &quot;Stacks[0].Outputs[?OutputKey=='PublicSubnet1'].OutputValue&quot; --output text)\nAUTH_ECS_PUBLICSUBNET_2=$(aws cloudformation describe-stacks --stack-name ecsplatform --query &quot;Stacks[0].Outputs[?OutputKey=='PublicSubnet2'].OutputValue&quot; --output text)\nAUTH_ECS_PRIVATESUBNET_1=$(aws cloudformation describe-stacks --stack-name ecsplatform --query &quot;Stacks[0].Outputs[?OutputKey=='PrivateSubnet1'].OutputValue&quot; --output text)\nAUTH_ECS_PRIVATESUBNET_2=$(aws cloudformation describe-stacks --stack-name ecsplatform --query &quot;Stacks[0].Outputs[?OutputKey=='PrivateSubnet2'].OutputValue&quot; --output text)\nAUTH_ECS_SG=$(aws cloudformation describe-stacks --stack-name ecsplatform --query &quot;Stacks[0].Outputs[?OutputKey=='NoIngressSecurityGroup'].OutputValue&quot; --output text)\nAUTH_ECS_DOMAIN=www.example.com &lt;-- Change to a domain name you want to use for this solution for this solution\n</code></pre>\n<p>You will set additional variables later, but these are enough to begin building your solution.</p>\n<h4><a id=\"Configure_the_security_group_rules_needed_for_web_traffic_access_95\"></a><strong>Configure the security group rules needed for web traffic access</strong></h4>\n<p>When users access the ALB, the security group attached to it needs to allow ingress port 443 (https) traffic. In addition, when the ALB forwards the web traffic to the Amazon ECS tasks there needs to be a ingress rules attached to the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> container instances that allows ingress port 80 (http) traffic.</p>\n<p>You can achieve this access with the following:</p>\n<pre><code class=\"lang-\">aws ec2 authorize-security-group-ingress \\\n --group-id $AUTH_ECS_SG \\\n --protocol tcp \\\n --port 443 \\\n --cidr 0.0.0.0/0\n \naws ec2 authorize-security-group-ingress \\\n--group-id $AUTH_ECS_SG \\\n--protocol tcp \\\n--port 80 \\\n--cidr 0.0.0.0/0\n</code></pre>\n<h4><a id=\"Create_a_public_Application_Load_Balancer_114\"></a><strong>Create a public Application Load Balancer</strong></h4>\n<p>As described earlier, the ALB will receive and terminate all client requests to validate for authentication using <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a>. The ALB also handles TLS offloading where the TLS certificates for the domain name will be deployed on it.</p>\n<p>To create the ALB do the below:</p>\n<pre><code class=\"lang-\">AUTH_ECS_ALBARN=$(aws elbv2 create-load-balancer --name $AUTH_ECS_CLUSTER --subnets $AUTH_ECS_PUBLICSUBNET_1 $AUTH_ECS_PUBLICSUBNET_2 --security-groups $AUTH_ECS_SG --query 'LoadBalancers[0].LoadBalancerArn' --output text)\n\nAUTH_ECS_ALB_DNS=$(aws elbv2 describe-load-balancers --load-balancer-arns $AUTH_ECS_ALBARN --query 'LoadBalancers[0].DNSName' --output text)\n</code></pre>\n<h4><a id=\"Configure_a_Domain_Name_System_125\"></a><strong>Configure a Domain Name System</strong></h4>\n<p>Clients will need a domain name that points to the ALB to type into their browsers.</p>\n<p>In this post, the Domain Name System (DNS) name is registered using the DNS Resolution service, <a href=\"https://aws.amazon.com/route53/\" target=\"_blank\">Amazon Route 53</a>.</p>\n<p>You can configure your domain name (such as <a href=\"http://www.example.com/\" target=\"_blank\">www.example.com</a> where it‘s known as the record and placed in a Route 53-hosted zone.</p>\n<h5><a id=\"Configure_both_the_Route_53_hosted_zone_and_record_132\"></a><strong>Configure both the Route 53 hosted zone and record</strong></h5>\n<p>If you already have a <code>Route53</code> publicly hosted zone for the apex domain and this is the location where you plan to add the record, then you will set its host zone ID (<code>AUTH_ECS_R53HZ</code>). For more information, see the hosted <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/SOA-NSrecords.html#NSrecords\" target=\"_blank\">zone ID</a> documentation.</p>\n<p>The first command line shown below demonstrates how to identify a hosted zone ID. You can substitute <a href=\"http://example.com/\" target=\"_blank\"><em>example.com</em></a> for your apex domain name. The other commands create a record that points to the ALB.</p>\n<pre><code class=\"lang-\">AUTH_ECS_R53HZ=$(aws route53 list-hosted-zones-by-name --dns-name example.com --query 'HostedZones[0].Id' --output text | grep -o '/hostedzone/.*' | cut -b 13-27) \n\ncat &lt;&lt; EOF &gt; dnsrecord.json\n{\n &quot;Comment&quot;: &quot;CREATE a DNS record that points to the ALB&quot;,\n &quot;Changes&quot;: [\n {\n &quot;Action&quot;: &quot;CREATE&quot;,\n &quot;ResourceRecordSet&quot;: {\n &quot;Name&quot;: &quot;$AUTH_ECS_DOMAIN&quot;,\n &quot;Type&quot;: &quot;CNAME&quot;,\n &quot;TTL&quot;: 300,\n &quot;ResourceRecords&quot;: [\n {\n &quot;Value&quot;: &quot;$AUTH_ECS_ALB_DNS&quot;\n }\n ]\n }\n }\n ]\n}\nEOF \naws route53 change-resource-record-sets --hosted-zone-id $AUTH_ECS_R53HZ --change-batch file://dnsrecord.json\n</code></pre>\n<h4><a id=\"Request_a_public_certificate_163\"></a><strong>Request a public certificate</strong></h4>\n<p>To ensure that web traffic sent by clients to the ALB is encrypted, integrate an ACM (<a href=\"https://docs.aws.amazon.com/acm/?id=docs_gateway\" target=\"_blank\">Amazon Web Services Certificate Manager</a> Certificate into the ALB’s listener. This ensures that the ALB serves HTTPS traffic and communications from clients to ALB is encrypted. Public SSL/TLS certificates provisioned through Amazon Web Services Certificate Manager are <a href=\"https://aws.amazon.com/certificate-manager/pricing/\" target=\"_blank\">free</a>. You pay only for the Amazon Web Services resources you create to run your application.</p>\n<h5><a id=\"Provision_an_ACM_certificate_167\"></a><strong>Provision an ACM certificate</strong></h5>\n<pre><code class=\"lang-\">AUTH_ECS_ACM_CERT_ARN=$(aws acm request-certificate \\\n --domain-name $AUTH_ECS_DOMAIN \\\n --validation-method DNS \\\n --region $AUTH_ECS_REGION \\\n --query 'CertificateArn' \\\n --output text)\n</code></pre>\n<p>When you create an SSL/TLS Certificate using ACM, it will try to confirm that you’re the owner of the domain name before fully provisioning the certificate for you to use. One method of confirmation is through DNS validation.</p>\n<p>Through this method ACM creates two CNAME records that you must add in your Route53 hosted zone.</p>\n<p>To add the ACM CNAME records in your Route53 hosted zones:</p>\n<pre><code class=\"lang-\">cat &lt;&lt; EOF &gt; acm_validate_cert_dns.json\n{\n &quot;Changes&quot;:[\n {\n &quot;Action&quot;: &quot;UPSERT&quot;,\n &quot;ResourceRecordSet&quot;:{\n &quot;Name&quot;: &quot;$(aws acm describe-certificate --certificate-arn $AUTH_ECS_ACM_CERT_ARN --query 'Certificate.DomainValidationOptions[].ResourceRecord[].Name' --output text)&quot;,\n &quot;Type&quot;: &quot;CNAME&quot;,\n &quot;TTL&quot;: 300,\n &quot;ResourceRecords&quot;: [\n {\n &quot;Value&quot;: &quot;$(aws acm describe-certificate --certificate-arn $AUTH_ECS_ACM_CERT_ARN --query 'Certificate.DomainValidationOptions[].ResourceRecord[].Value' --output text)&quot;\n }\n ]\n }\n }\n ]\n }\nEOF\naws route53 change-resource-record-sets \\\n --hosted-zone-id $AUTH_ECS_R53HZ \\\n --change-batch file://acm_validate_cert_dns.json\n</code></pre>\n<p>It takes some time before the certificate will change from ‘Pending Validation’ to ‘Success’.</p>\n<p>Once the status shows ‘Issued’ on the <a href=\"https://console.aws.amazon.com/acm/\" target=\"_blank\">ACM console</a> then you can use the certificate.</p>\n<h5><a id=\"Create_an_HTTPS_listener_and_listener_rule_on_the_ALB_213\"></a><strong>Create an HTTPS listener and listener rule on the ALB</strong></h5>\n<p>Now that you’ve created the ALB. In addition, you’ve also created a certificate to configure the HTTPS listener to accept incoming HTTPS request from clients and to terminate them.</p>\n<p>You integrate the certificate into the listener and add a default rule action on the ALB:</p>\n<pre><code class=\"lang-\">cat &lt;&lt; EOF &gt; listener-defaultaction.json\n[\n {\n &quot;Type&quot;: &quot;redirect&quot;,\n &quot;RedirectConfig&quot;: {\n &quot;Protocol&quot;: &quot;HTTPS&quot;,\n &quot;Port&quot;: &quot;443&quot;,\n &quot;Host&quot;: &quot;$AUTH_ECS_DOMAIN&quot;,\n &quot;StatusCode&quot;: &quot;HTTP_301&quot;\n }\n }\n]\nEOF\nAUTH_ECS_ALBLISTENER=$(aws elbv2 create-listener \\\n --load-balancer-arn $AUTH_ECS_ALBARN \\\n --protocol HTTPS \\\n --port 443 \\\n --certificates CertificateArn=$AUTH_ECS_ACM_CERT_ARN \\\n --ssl-policy ELBSecurityPolicy-2016-08 \\\n --default-actions file://listener-defaultaction.json \\\n --query 'Listeners[0].ListenerArn' \\\n --output text)\n</code></pre>\n<h4><a id=\"Create_an_Amazon_Cognito_user_pool_243\"></a><strong>Create an Amazon Cognito user pool</strong></h4>\n<p>As previously described, <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a> provides user management, authentication and authorization for applications where users can login in directly or through their pre-existing social/corporate credentials.</p>\n<p>Create a user pool, which is a user directory in Amazon Cognito that helps clients to access the website. Clients sign in with their credentials before they get access to the site.</p>\n<p>To fully configure Amazon Cognito for integration with the ALB, create a <a href=\"https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html\" target=\"_blank\">user pool</a>, a user pool <a href=\"https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html\" target=\"_blank\">application client</a>, and a <a href=\"https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-domain.html\" target=\"_blank\">user pool domain</a>. The following steps show you how to accomplish these tasks.</p>\n<h5><a id=\"Create_an_Amazon_Cognito_user_pool_250\"></a><strong>Create an Amazon Cognito user pool</strong></h5>\n<pre><code class=\"lang-\">AUTH_COGNITO_USER_POOL_ID=$(aws cognito-idp create-user-pool \\\n --pool-name ${AUTH_ECS_CLUSTER}_Pool \\\n --username-attributes email \\\n --username-configuration=CaseSensitive=false \\\n --region $AUTH_ECS_REGION \\\n --query 'UserPool.Id' \\\n --auto-verified-attributes email \\\n --output text)\n</code></pre>\n<h5><a id=\"Create_an_Amazon_Cognito_user_pool_application_client_263\"></a><strong>Create an Amazon Cognito user pool application client</strong></h5>\n<pre><code class=\"lang-\">AUTH_COGNITO_USER_POOL_CLIENT_ID=$(aws cognito-idp create-user-pool-client \\\n --client-name ${AUTH_ECS_CLUSTER}_AppClient \\\n --user-pool-id $AUTH_COGNITO_USER_POOL_ID \\\n --generate-secret \\\n --allowed-o-auth-flows &quot;code&quot; \\\n --allowed-o-auth-scopes &quot;openid&quot; \\\n --callback-urls &quot;https://${AUTH_ECS_DOMAIN}/oauth2/idpresponse&quot; \\\n --supported-identity-providers &quot;COGNITO&quot; \\\n --allowed-o-auth-flows-user-pool-client \\\n --region $AUTH_ECS_REGION \\\n --query 'UserPoolClient.ClientId' \\\n --output text)\n</code></pre>\n<h5><a id=\"Create_an_Amazon_Cognito_user_pool_domain_280\"></a><strong>Create an Amazon Cognito user pool domain</strong></h5>\n<pre><code class=\"lang-\">AUTH_COGNITO_USER_POOL_ARN=$(aws cognito-idp describe-user-pool --user-pool-id $AUTH_COGNITO_USER_POOL_ID --query 'UserPool'.Arn --output text)\n\nAUTH_COGNITO_DOMAIN=(authecsblog$(whoami))\n\naws cognito-idp create-user-pool-domain \\\n --user-pool-id $AUTH_COGNITO_USER_POOL_ID \\\n --region $AUTH_ECS_REGION \\\n --domain $AUTH_COGNITO_DOMAIN\n</code></pre>\n<h5><a id=\"Create_and_configure_a_target_group_for_the_ALB_293\"></a><strong>Create and configure a target group for the ALB</strong></h5>\n<p>Create a target group for the ALB. The <a href=\"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/elbv2/create-target-group.html\" target=\"_blank\">target group</a> is used to route requests to the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> tasks.</p>\n<p>When an ALB receives the HTTPS traffic from the web clients, it routes the requests to the target group (after authentication of the client has occurred) for a web response. (Amazon ECS tasks are registered to the target group in a later section “Configuring the ECS Service”).</p>\n<p>Create an empty target group:</p>\n<pre><code class=\"lang-\">AUTH_ECS_ALBTG=$(aws elbv2 create-target-group \\\n --name ${AUTH_ECS_CLUSTER}-tg \\\n --protocol HTTP \\\n --port 80 \\\n --target-type instance \\\n --vpc-id $AUTH_ECS_VPC \\\n --query 'TargetGroups[0].TargetGroupArn' \\\n --output text)\n</code></pre>\n<h5><a id=\"Hostbased_routing_and_an_authentication_rule_on_the_ALB_311\"></a><strong>Host-based routing and an authentication rule on the ALB</strong></h5>\n<p>The ALB routes requests based on the host name in the HTTP host header.</p>\n<p>It is possible to configure multiple domains that all point to a single ALB because the ALB can route requests based on the incoming host header and forward the requests to the right target group for handling.</p>\n<p>You can configure an <a href=\"https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#configure-user-authentication\" target=\"_blank\">authentication rule</a> which tells the ALB what to do to the incoming requests. In this post, we want the requests to first be authenticated and, if successful, the request should get forwarded to the target group we created earlier.</p>\n<h5><a id=\"Configure_hostbased_routing_and_an_authentication_rule_on_the_ALB_318\"></a><strong>Configure host-based routing and an authentication rule on the ALB</strong></h5>\n<pre><code class=\"lang-\">cat &lt;&lt; EOF &gt; actions-authenticate.json\n [\n {\n &quot;Type&quot;: &quot;authenticate-cognito&quot;,\n &quot;AuthenticateCognitoConfig&quot;: {\n &quot;UserPoolArn&quot;: &quot;$AUTH_COGNITO_USER_POOL_ARN&quot;,\n &quot;UserPoolClientId&quot;:\n&quot;$AUTH_COGNITO_USER_POOL_CLIENT_ID&quot;,\n &quot;UserPoolDomain&quot;: &quot;$AUTH_COGNITO_DOMAIN&quot;,\n &quot;SessionCookieName&quot;: &quot;AWSELBAuthSessionCookie&quot;,\n &quot;Scope&quot;: &quot;openid&quot;,\n &quot;OnUnauthenticatedRequest&quot;: &quot;authenticate&quot;\n },\n &quot;Order&quot;: 1\n },\n {\n &quot;Type&quot;: &quot;forward&quot;,\n &quot;TargetGroupArn&quot;: &quot;$AUTH_ECS_ALBTG&quot;,\n &quot;Order&quot;: 2\n }\n ]\nEOF\n\ncat &lt;&lt; EOF &gt; conditions-hostrouting.json\n[\n {\n &quot;Field&quot;: &quot;host-header&quot;,\n &quot;HostHeaderConfig&quot;: {\n &quot;Values&quot;: [&quot;$AUTH_ECS_DOMAIN&quot;]\n }\n }\n]\nEOF\n\naws elbv2 create-rule \\\n --listener-arn $AUTH_ECS_ALBLISTENER \\\n --priority 20 \\\n --conditions file://conditions-hostrouting.json \\\n --actions file://actions-authenticate.json\n</code></pre>\n<h4><a id=\"Amazon_ECS_configuration_362\"></a><strong>Amazon ECS configuration</strong></h4>\n<p>The ALB and <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a> are now configured for processing incoming requests and authentication.</p>\n<p>Next you will configure <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> to orchestrate and deploy running tasks to generate response for the client’s web request.</p>\n<p>An Amazon ECS cluster is a logical grouping of tasks or services. Amazon ECS instances are part of the Amazon ECS infrastructure registered to a cluster that the Amazon ECS tasks run on.</p>\n<p>Two <code>t3.small</code> Amazon ECS instances will be configured to run the tasks. Amazon ECS will run and maintain two tasks, which are configured based on parameters and settings contained in the task definition (a <code>JSON</code> text file).</p>\n<p>For more information on Amazon ECS basics, constructs, and orchestration read the <a href=\"https://docs.aws.amazon.com/AmazonECS/latest/developerguide/welcome-features.html\" target=\"_blank\">Amazon ECS components</a> documentation.</p>\n<h5><a id=\"Configure_the_Amazon_ECS_CLI_373\"></a><strong>Configure the Amazon ECS CLI</strong></h5>\n<p><a href=\"https://docs.aws.amazon.com/AmazonECS/latest/developerguide/welcome-features.html\" target=\"_blank\">Amazon ECS CLI</a> is the tool that you’d use to configure and launch the Amazon ECS components.</p>\n<p>To download Amazon ECS CLI, follow the following steps:</p>\n<p>Amazon ECS CLI needs a CLI profile, to proceed generate an access key ID, and access key using the <a href=\"https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys\" target=\"_blank\">Amazon Web Services credentials documentation</a>.</p>\n<p>Set the <code>$AWS_ACCESS_KEY_ID</code> and <code>$AWS_SECRET_ACCESS_KEY</code> variables to the copied values generated by <a href=\"https://docs.aws.amazon.com/iam/?id=docs_gateway\" target=\"_blank\">Amazon Web Services IAM</a>.</p>\n<h5><a id=\"Configure_the_Amazon_ECS_CLI_for_a_CLI_profile_382\"></a><strong>Configure the Amazon ECS CLI for a CLI profile</strong></h5>\n<pre><code class=\"lang-\">ecs-cli configure profile --profile-name profile_name --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY\n</code></pre>\n<h5><a id=\"Create_the_Amazon_ECS_cluster_388\"></a><strong>Create the Amazon ECS cluster</strong></h5>\n<p>Create the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> cluster, which consists of two <code>t3.small</code> instance types deployed in the VPC and residing in the two private subnets from earlier. For the instance-role, use the <a href=\"https://docs.aws.amazon.com/iam/?id=docs_gateway\" target=\"_blank\">Amazon Web Services IAM</a> role created when configuring the <a href=\"https://docs.aws.amazon.com/cloud9/?id=docs_gateway\" target=\"_blank\">Amazon Web Services Cloud9</a> environment workspace (<code>ecsworkshop-admin</code>).</p>\n<p>The first command creates a keypair and the second command configures the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> cluster. The keypair is useful if you need to SSH into the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> instances for troubleshooting.</p>\n<h5><a id=\"Configure_the_Amazon_EC2_key_pair_and_bring_up_the_ECS_cluster_393\"></a><strong>Configure the Amazon EC2 key pair and bring up the ECS cluster</strong></h5>\n<pre><code class=\"lang-\">aws ec2 create-key-pair \\\n --key-name $AUTH_ECS_CLUSTER \\\n --key-type rsa \\\n --query &quot;KeyMaterial&quot; \\\n --output text &gt; $AUTH_ECS_CLUSTER.pem\n \necs-cli up --instance-role ecsworkshop-admin --cluster $AUTH_ECS_CLUSTER --vpc $AUTH_ECS_VPC --subnets $AUTH_ECS_PRIVATESUBNET_1,$AUTH_ECS_PRIVATESUBNET_2 --port 443 --region $AUTH_ECS_REGION --keypair $AUTH_ECS_CLUSTER --size 2 --instance-type t3.small --security-group $AUTH_ECS_SG --launch-type EC2\n</code></pre>\n<p>The cluster creation will take some time, when fully deployed the <a href=\"https://docs.aws.amazon.com/cloudformation/?id=docs_gateway\" target=\"_blank\">Amazon Web Services CloudFormation</a> stack status will output ‘Cluster creation succeeded’.</p>\n<h5><a id=\"Configure_the_Amazon_Web_Services_Region_and_ECS_cluster_name_using_the_configure_command_407\"></a><strong>Configure the Amazon Web Services Region and ECS cluster name using the configure command:</strong></h5>\n<pre><code class=\"lang-\">ecs-cli configure --region $AUTH_ECS_REGION --cluster $AUTH_ECS_CLUSTER --default-launch-type EC2 --config-name $AUTH_ECS_CLUSTER\n</code></pre>\n<p>The <code>EC2</code> launch type, with <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> instances, is created and launched in your VPC. If you prefer not to manage the underlying instances hosting the tasks, then Fargate launch type is the option to use. <a href=\"https://aws.amazon.com/fargate/\" target=\"_blank\">Fargate</a> is the serverless way to host your Amazon ECS workloads.</p>\n<h5><a id=\"Create_the_ECS_service_415\"></a><strong>Create the ECS service</strong></h5>\n<p>The <code>ecs-cli compose service</code> up command will create the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> service and tasks from a Docker Compose file (<code>ecsauth-compose.yaml</code>) that you create. This service is configured to use the ALB that you created earlier. A task definition is created by the command.</p>\n<p>The Docker Compose file contains the configuration settings that the Amazon ECS service is spun up with. This includes the Docker image to pull and use, the ports to expose on the Amazon ECS instance, and the Amazon ECS task for network forwarding. In this post, we configured it to use the Amazon Web Services published sample demo PHP application verified and published to <a href=\"https://hub.docker.com/r/amazon/amazon-ecs-sample\" target=\"_blank\">Docker Hub</a>. Also, the Transmission Control Protocol (TCP) <code>port 80</code> will be opened on the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> instance and traffic received on this port will be forwarded to the task on TCP <code>port 80</code>).</p>\n<h5><a id=\"Configuring_the_ECS_service_421\"></a><strong>Configuring the ECS service</strong></h5>\n<pre><code class=\"lang-\">cat &lt;&lt; EOF &gt; ecsauth-compose.yml\nversion: '2'\nservices:\n web:\n image: amazon/amazon-ecs-sample\n ports:\n - &quot;80:80&quot;\nEOF\necs-cli compose --project-name ${AUTH_ECS_CLUSTER}service --file ecsauth-compose.yml service up --target-group-arn $AUTH_ECS_ALBTG --container-name web --container-port 80 --role ecsServiceRole\necs-cli compose --project-name ${AUTH_ECS_CLUSTER}service --file ecsauth-compose.yml service scale 2\n</code></pre>\n<h5><a id=\"Testing_the_solution_end_to_end_436\"></a><strong>Testing the solution end to end</strong></h5>\n<p>We now the have working components of the solution. To test the solution end to end, you can navigate to the https site of the domain name used in your browser (such as <a href=\"https://www.example.com/\" target=\"_blank\">https://www.example.com</a>.</p>\n<pre><code class=\"lang-\">echo $AUTH_ECS_DOMAIN\n</code></pre>\n<p>The sequence of events that follows is as we described in the flow of how the ALB authenticates users using <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a> (section “Flow of how Application Load Balancer authenticates users using Amazon Cognito”).</p>\n<p>After redirection by the ALB to the Amazon Cognito configured domain’s login page (a hosted UI by Amazon Cognito), enter input your credentials.</p>\n<p>Since this is the first time the page is accessed we will sign up as a new user. Amazon Cognito stores this information in the user pool. If you navigate to the Amazon Cognito user pool console after, you’ll see this new user.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/9c20b77ea29d48ca97b15ca3444f24c6_image.png\" alt=\"image.png\" /></p>\n<p>After signing in to the ALB, it redirects you to the landing page of the sample demonstration PHP application, which is shown in the diagram below.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/9312d6ba440a4662b85d364643abeeaf_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"User_claims_encoding_and_security_456\"></a><strong>User claims encoding and security</strong></h5>\n<p>In this post, we configured the target group to use HTTP, because the ALB has handled the TLS offloading. However, for enhanced security, you should restrict the traffic getting to the <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS instances</a> to only the load balancer using the security group.</p>\n<p>After the load balancer authenticates a user successfully, it passes the claims of the user to the target. If you inspect traffic forwarded to the sample demonstration application through custom HTTP header logging in your access logs, you can see three HTTP headers. These headers contain information about the user claims and is signed by the ALB with a signature and algorithm that you can verify.</p>\n<p>The three HTTP headers <a href=\"https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#user-claims-encoding\" target=\"_blank\">include</a> the following:</p>\n<pre><code class=\"lang-\">x-amzn-oidc-accesstoken\n</code></pre>\n<p>The access token from the token endpoint, in plain text.</p>\n<pre><code class=\"lang-\">x-amzn-oidc-identity\n</code></pre>\n<p>The subject field (sub) from the user info endpoint, in plain text.</p>\n<pre><code class=\"lang-\">x-amzn-oidc-data\n</code></pre>\n<p>The user claims, in JSON web tokens (JWT) format.</p>\n<p>From information encoded in the <code>x-amzn-oidc-data</code>, it is possible to extract information about the user.</p>\n<p>The following is an example Python 3.x application that can decode the payload portion of the <code>x-amzn-oidc-data</code> to reveal the user claims passed by <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a>.</p>\n<pre><code class=\"lang-\">import jwt\nimport requests\nimport base64\nimport json\n\n# Step 1: Get the key id from JWT headers (the kid field)\n;\nencoded_jwt = headers.dict['x-amzn-oidc-data']\njwt_headers = encoded_jwt.split('.')[0]\ndecoded_jwt_headers = base64.b64decode(jwt_headers)\ndecoded_jwt_headers = decoded_jwt_headers.decode(&quot;utf-8&quot;)\ndecoded_json = json.loads(decoded_jwt_headers)\nkid = decoded_json['kid']\n\n# Step 2: Get the public key from regional endpoint\nurl = 'https://public-keys.auth.elb.' + region + '.amazonaws.com/' + kidreq = requests.get(url)\npub_key = req.text\n\n# Step 3: Get the payload\npayload = jwt.decode(encoded_jwt, pub_key, algorithms=['ES256'])\n</code></pre>\n<h3><a id=\"Cleanup_508\"></a><strong>Cleanup</strong></h3>\n<p>Now that you are done building the solution and testing it to clean up all the resources you can run the following commands:</p>\n<pre><code class=\"lang-\">aws elbv2 delete-load-balancer \\\n --load-balancer-arn $AUTH_ECS_ALBARN\n\naws ecs delete-service --cluster $AUTH_ECS_CLUSTER --service ${AUTH_ECS_CLUSTER}service –force\n\ncontainerinstance1=$(aws ecs list-container-instances --cluster $AUTH_ECS_CLUSTER --query 'containerInstanceArns[0]' --output text)\ncontainerinstance2=$(aws ecs list-container-instances –cluster\n$AUTH_ECS_CLUSTER --query 'containerInstanceArns[1]' --output text)\n\naws ecs deregister-container-instance \\\n --cluster $AUTH_ECS_CLUSTER \\\n --container-instance $containerinstance1 \\\n --force\n\naws ecs deregister-container-instance \\\n --cluster $AUTH_ECS_CLUSTER \\\n --container-instance $containerinstance2 \\\n --force\n\naws ecs delete-cluster --cluster $AUTH_ECS_CLUSTER\n\naws ecs deregister-task-definition --task-definition ${AUTH_ECS_CLUSTER}service:1\naws acm delete-certificate --certificate-arn $AUTH_ECS_ACM_CERT_ARN\naws route53 delete-hosted-zone --id $AUTH_ECS_R53HZ\n\naws cognito-idp delete-user-pool-domain \\\n --user-pool-id $AUTH_COGNITO_USER_POOL_ID \\\n --domain $AUTH_COGNITO_DOMAIN\n\naws cognito-idp delete-user-pool --user-pool-id $AUTH_COGNITO_USER_POOL_ID\n\naws elbv2 delete-target-group \\\n --target-group-arn $AUTH_ECS_ALBTG\n \naws cloudformation delete-stack \\\n --stack-name amazon-ecs-cli-setup-$AUTH_ECS_CLUSTER\n \naws cloudformation delete-stack \\\n --stack-name ecsplatform\n \naws ec2 delete-key-pair --key-name $AUTH_ECS_CLUSTER\n</code></pre>\n<h3><a id=\"Conclusion_555\"></a><strong>Conclusion</strong></h3>\n<p>In this post, we showed you how to authenticate users accessing your containerized application without writing authentication code, using the ALB’s inbuilt integration with <a href=\"https://docs.aws.amazon.com/cognito/?id=docs_gateway\" target=\"_blank\">Amazon Cognito</a>. Maintaining and securing user management and authentication is offloaded from the application, which allows you to focus on building core business logic into the application. You don’t need to worry about platform tasks for managing, scheduling, and scaling containers for the web traffic because <a href=\"https://docs.aws.amazon.com/ecs/?id=docs_gateway\" target=\"_blank\">Amazon ECS</a> handles all of that.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/1265d526bce14616b441ef6fbbdad417_image.png\" alt=\"image.png\" /></p>\n<p><strong>Chiedu Eluehike</strong></p>\n<p>an interest in poker.</p>\n<p>Chiedu is an Enterprise Solutions Architect at Amazon Web Services currently based out of Sydney, Australia. In his role, he helps customers achieve their business objectives and uncover opportunities for value using Cloud Solutions. He is CCIE#48238. Outside of work, he enjoys watching and playing soccer, listening to podcasts, trying new food in restaurants, mindfulness meditation, and has taken</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭