Web application access control patterns using AWS services
AWS Architecture BlogWeb application access control patterns using AWS servicesby Zili Gao | on05 AUG 2022| inAmazon API Gateway,Amazon CloudFront,Amazon Cognito,Amazon EC2,Architecture,AWS Lambda,AWS Secrets Manager|Permalink|ShareThe web application client-server pattern is widely adopted. The access control allows only authorized clients to access the backend server resources by authenticating the client and providing granular-level access based on who the client is.This post focuses on three solution architecture patterns that prevent unauthorized clients from gaining access to web application backend servers. There are multiple AWS services applied in these architecture patterns that meet the requirements of different use cases.OAuth 2.0 authentication code flowFigure 1 demonstrates the fundamentals to all the architectural patterns discussed in this post. The blogUnderstanding Amazon Cognito user pool OAuth 2.0 grantsdescribes the details of different OAuth 2.0 grants, which can vary the flow to some extent.Figure 1. A typical OAuth 2.0 authentication code flowThe architecture patterns detailed in this post useAmazon Cognitoas the authorization server, andAmazon Elastic Compute Cloudinstance(s) as resource server. The client can be any front-end application, such as a mobile application, that sends a request to the resource server to access the protected resources.Pattern 1Figure 2 is an architecture pattern that offloads the work of authenticating clients toApplication Load Balancer (ALB).Figure 2. Application Load Balancer integration with Amazon CognitoALB can be used to authenticate clients through the user pool of Amazon Cognito:The client sends HTTP request to ALB endpoint without authentication-session cookies.ALB redirects the request to Amazon Cognito authentication endpoint. The client is authenticated by Amazon Cognito.The client is directed back to the ALB with the authentication code.The ALB uses the authentication code to obtain the access token from the Amazon Cognito token endpoint and also uses the access token to get client’s user claims fromAmazon Cognito UserInfo endpoint.The ALB prepares the authentication session cookie containing encrypted data and redirects client’s request with the session cookie. The client uses the session cookie for all further requests. The ALB validates the session cookie and decides if the request can be passed through to its targets.The validated request is forwarded to the backend instances with the ALB adding HTTP headers that contain the data from the access token and user-claims information.The backend server can use the information in the ALB added headers for granular-level permission control.The key takeaway of this pattern is that the ALB maintains the whole authentication context by triggering client authentication with Amazon Cognito and prepares the authentication-session cookie for the client. TheAmazon Cognito sign-in callback URLpoints to the ALB, which allows the ALB access to the authentication code.More details about this pattern can be found in the documentationAuthenticate users using an Application Load Balancer.Pattern 2The pattern demonstrated in Figure 3 offloads the work of authenticating clients toAmazon API Gateway.Figure 3. Amazon API Gateway integration with Amazon CognitoAPI Gateway can support both REST and HTTP API.API Gatewayhas integration with Amazon Cognito, whereas it can also havecontrol access to HTTP APIs with a JSON Web Token (JWT) authorizer, which interacts with Amazon Cognito. The ALB can be integrated with API Gateway. The client is responsible for authenticating with Amazon Cognito to obtain the access token.The client starts authentication with Amazon Cognito to obtain the access token.The client sends REST API or HTTP API request with a header that contains the access token.The API Gateway is configured to have:Amazon Cognito user pool as the authorizer to validate the access token in REST API request, orA JWT authorizer, which interacts with the Amazon Cognito user pool to validate the access token in HTTP API request.After the access token is validated, the REST or HTTP API request is forwarded to the ALB, and:The API Gateway can route HTTP API to private ALB via aVPC endpoint.If a public ALB is used, the API Gateway can route both REST API and HTTP API to the ALB.API Gateway cannot directly route REST API to a private ALB. It can route to a private Network Load Balancer (NLB) via a VPC endpoint. The private ALB can be configured as the NLB’s target.The key takeaways of this pattern are:API Gateway has built-in features to integrate Amazon Cognito user pool to authorize REST and/or HTTP API request.An ALB can be configured to only accept the HTTP API requests from the VPC endpoint set by API Gateway.Pattern 3Amazon CloudFrontis able to triggerAWS Lambdafunctions deployed at AWS edge locations. This pattern (Figure 4) utilizes a feature ofLambda@Edge, where it can act as an authorizer to validate the client requests that use an access token, which is usually included in HTTP Authorization header.Figure 4. Using Amazon CloudFront and AWS Lambda@Edge with Amazon CognitoThe client can have an individual authentication flow with Amazon Cognito to obtain the access token before sending the HTTP request.The client starts authentication with Amazon Cognito to obtain the access token.The client sends a HTTP request with Authorization header, which contains the access token, to the CloudFront distribution URL.TheCloudFront viewer request eventtriggers the launch of the function at Lambda@Edge.The Lambda function extracts the access token from the Authorization header, andvalidates the access token with Amazon Cognito. If the access token is not valid, the request is denied.If the access token is validated, the request is authorized and forwarded by CloudFront to the ALB. CloudFront is configured to add a custom header with a value that can only be shared with the ALB.The ALB sets a listener rule to check if the incoming request has the custom header with the shared value. This makes sure the internet-facing ALB only accepts requests that are forwarded by CloudFront.To enhance the security, the shared value of the custom header can be stored inAWS Secrets Manager. Secrets Manager can trigger an associatedLambda function to rotate the secret valueperiodically.The Lambda function also updates CloudFront for the added custom header and ALB for the shared value in the listener rule.The key takeaways of this pattern are:By default, CloudFront will remove the authorization header before forwarding the HTTP request to its origin. CloudFront needs to be configured toforward the Authorization header to the originof the ALB. The backend server uses the access token to apply granular levels of resource access permission.The use of Lambda@Edge requires the function to sit in us-east-1 region.The CloudFront-added custom header’s value is kept as a secret that can only be shared with the ALB.ConclusionThe architectural patterns discussed in this post are token-based web access control methods that are fully supported by AWS services. The approach offloads the OAuth 2.0 authentication flow from the backend server to AWS services. The services managed by AWS can provide the resilience, scalability, and automated operability for applying access control to a web application.Zili GaoZili Gao is a Partner Solutions Architect with AWS Worldwide Public Sector. As a generalist, he works with AWS partners on their solutions in diversified technology domains. He also supports customer enablement, further promoting AWS best practices. Outside of work, Zili enjoys swimming and reading philosophy books.
The web application client-server pattern is widely adopted. The access control allows only authorized clients to access the backend server resources by authenticating the client and providing granular-level access based on who the client is. This post focuses on three solution architecture patterns that prevent unauthorized clients from gaining access to web application backend servers. […]
Zili Gao
Amazon API Gateway Amazon CloudFront Amazon Cognito Amazon EC2 Architecture AWS Lambda AWS Secrets Manager