사용자 인증
개요
프라이빗 콘텐츠를 노출하는 웹 애플리케이션에는 승인된 사용자만 콘텐츠에 액세스할 수 있도록 하는 액세스 제어 메커니즘이 필요합니다. 사용자 인증이 필요한 SPA 기반 내부 포털과 기밀 파일 다운로드 등을 예로 들 수 있습니다. 액세스 제어는 사용 사례에 따라 오리진 수준 또는 CDN 수준에서 구현될 수 있습니다.
일반 사용 사례
오리진 기반 인증
캐싱이 활성화되지 않은 상태에서 CloudFront를 리버스 프록시로 사용하는 경우(예: 관리형 캐싱 정책에 캐싱 비활성화가 구성된 경우) 간단히 오리진의 기본 인증 기능(예: API Gateway)을 사용할 수 있습니다. 이 기능이 제대로 작동하려면 인증 헤더와 같은 승인 정보를 전달하는 요청 속성을 오리진에 전달하도록 오리진 요청 정책을 구성하세요.
콘텐츠를 캐싱할 수 있지만 자체 인프라에서 인증을 계속 관리하고 싶다면 Lambda@Edge를 사용하여 CloudFront를 인증 서버와 통합하는 것을 고려해 보세요. 이 아키텍처를 사용하면 CloudFront 캐싱의 이점을 활용할 수 있습니다. 이 구현에 대한 자세한 내용은 이 블로그를 읽어 보세요.
웹 애플리케이션 구성 요소의 인증 로직을 CloudFront로 오프로드하려면 다음 섹션을 살펴보세요.
서명된 토큰을 사용한 CloudFront 기반 인증
CloudFront는 서명된 URL 또는 서명된 쿠키를 사용하여 기본 인증 메커니즘을 제공합니다. 이 방법을 사용하려면 설명서에 설명된 단계를 따르세요.
- 서명 키 그룹을 사용하여 토큰 서명을 위한 비대칭 암호화 키를 구성합니다.
- 인증 워크플로우에서 제공된 리소스 URL의 쿼리 파라미터 또는 쿠키에 필요한 토큰 필드를 추가합니다. 토큰에는 만료일, 서명 키 ID, 정책 및 서명이 포함됩니다. 정책을 통해 CloudFront의 토큰 검증 테스트 통과 요청 시 충족해야 하는 조건을 정의할 수 있습니다. 예를 들어 사용자 지정 정책을 사용하여 특정 경로로 시작하는 모든 URL에 유효한 토큰을 생성할 수 있습니다.
- 프라이빗 콘텐츠에 사용되는 CloudFront의 캐시 동작에서 서명을 활성화합니다. 그 시점부터 모든 요청은 토큰 검증을 위해 CloudFront에 의해 제어됩니다. 승인되지 않은 요청은 403 오류를 수신하며, 이 오류는 CloudFront의 사용자 지정 오류 페이지 기능을 사용하여 사용자 지정할 수 있습니다.
aws-sdk를 사용하여 프라이빗 키로 유효한 토큰을 생성합니다. 예를 들어, Nodejs의 아래 코드는 2시간 동안 유효한 특정 객체 edge-image.jpg에 대해 CloudFront 서명된 URL을 생성합니다.
const AWS = require('aws-sdk');
// It's recommended not to store signing keys in code. The below is just an illustrative example.
const cloudfrontAccessKeyId = 'K25ULYFPSTHQP9';
const cloudFrontPrivateKey = '-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQ....2gvvIH\n-----END RSA PRIVATE KEY-----';
const signer = new AWS.CloudFront.Signer(cloudfrontAccessKeyId, cloudFrontPrivateKey);
const signedUrl = signer.getSignedUrl({
url: 'https://d3jqlnxofenq2x.cloudfront.net/edge-image.jpg',
expires: Math.floor((Date.now() + 2 * 60 * 60 * 1000) / 1000),
});
console.log(signedUrl);
위 코드 조각의 출력은 다음과 같습니다.
https://d3jqlnxofenq2x.cloudfront.net/edge-image.jpg?Expires=1660317158&Key-Pair-Id=K25ULYFP9THQP9&Signature=agW2XF9S5AW0YCc6c7pkCwccJmxaIAWFO~uXn9KtOXtz4JTY7eRF07opJiseGXJxzlMeD4V6FUH8I-gOH~Gvafa16RFV9IryxCyzL9mIYt-XbDKMrY0ONzTWUk2x16AKDK27VoUwEPiI9dpPXMp7f4MsrpKA-u6huZCsulh0~aAYN~x25uNoDO-WgZpfkKFeKc910u4PVnEaKLlZlpuJ0hqWUjMVPes9DfA~msToJeyjrVzLi2R8O8LuuYHsAMAHXr7E9qB8tAoDWz24CurCirxc6sB45Zc-oK9JigX0L4~F~F1TE9i39ysmQF4UrOyu0bp7MKGSDBwLE1P2C3gWNw__
CloudFront Functions를 사용한 CloudFront 기반 인증
CloudFront의 기본 서명 토큰이 인증 요구 사항을 충족하지 않는 경우 엣지 함수를 사용하여 사용자 지정 인증 로직을 구축할 수 있습니다. 예를 들어 대칭 암호화와 같은 토큰 서명에 다른 암호화를 사용하거나, 사용자 에이전트 헤더와 같은 비표준 속성을 서명에 포함하거나, 사용자 네트워크를 기반으로 조건부 토큰화 로직을 구현하고자 할 수 있습니다. 다음 사용자 지정 구현은 엣지 함수의 몇 가지 가능성을 보여줍니다.
- JWT 기반 토큰을 검증하는 CloudFront Functions. 참고로 CloudFront Functions는 현재 외부 네트워크 호출을 허용하지 않으므로 서명 키를 함수 코드에 저장해야 합니다. CloudFront Function 코드에 서명 키를 저장하는 위험을 줄이려면 코드에서 키를 수동으로 구성하지 말고, CloudFront에 배포하기 전에 키를 교체하고 함수 코드를 생성하는 자동화를 사용하세요. 이렇게 하면 키가 Github와 같은 퍼블릭 리포지토리에 업로드될 위험이 없습니다.
- AWS 솔루션: 엣지에서 미디어 전송 보호. 이 AWS 솔루션은 CloudFront Function을 사용하여 비디오 스트리밍에 적합한 사용자 지정 인증 메커니즘을 구현합니다.
- OpenID Connect를 사용하여 S3에 호스팅되는 단일 페이지 애플리케이션을 인증합니다. 이 솔루션은 AWS Secrets Manager를 사용하여 서명 키를 저장하고 Cognito 또는 Okta와 같은 외부 ID 제공업체(idP)와 함께 작업할 수 있습니다. 이 구현은 CloudFront Functions가 출시되기 전에 게시되었으므로 전적으로 Lambda@Edge를 사용하고 있습니다. 인증 부분에는 CloudFront Functions를 사용하고 IdP와의 통합에는 Lambda@Edge를 사용하도록 최적화할 수 있습니다.