Open binchoo opened 2 years ago
제목 | 내용 |
---|---|
Cookies.get('XSRF-TOKEN') returns undefined | 쿠키로 토큰을 내려줄 때, HttpOnly 쿠키라서 읽지 못 하는 현상. |
(SDK 설정 예)
@Configuration
public class AmazonS3Config {
@Bean
AmazonS3 amazonS3() throws IOException {
AmazonS3ClientBuilder clientBuilder = AmazonS3ClientBuilder.standard();
clientBuilder.setCredentials(credentialsProvider());
clientBuilder.setRegion("ap-northeast-1");
return clientBuilder.build();
}
@Bean
AWSCredentialsProvider credentialsProvider() throws IOException {
return new PropertiesFileCredentialsProvider(
new ClassPathResource("aws.properties").getFile().getAbsolutePath());
}
}
제목 | 내용 |
---|---|
Authenticating Requests: Using the Authorization Header | AWS에 인가된 AWS 요청 보내기 |
sig-v4-header-based-auth | AWS 요청에 도장을 찍기위한 계산 과정 |
https://awspolicygen.s3.amazonaws.com/policygen.html
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
유저에게 파일 업로드 할 S3 주소를 알려주어라.
방법1. S3 Presigned URL
을 생성해 내려주자.
클라이언트는 임시 싸인이 붙은 (TTL 있음) S3 자원 주소를 받는다. 이어서 클라이언트는 해당 주소로 PutObject 연산을 수행하면 된다.
단점: 인증 허점이 생긴다. Presigned URL이 다른 사람에게 공유되면 그 자는 스프링 시큐리티의 인증을 받지 않았는데도 파일을 업로드 할 수 있다. 이 단점은 유저 인증과 AWS 리소스 접근 권한 인증이 구분되어 있어서 발생한다. 즉, S3 접근 권한 인증이 유저 인증을 장담하지 않는다. 따라서 스프링 백엔드에서 추가적인 엔터티를 만들어 유저 인증과 S3 버킷 인증을 매핑해 보유하는 방식이 필요하다.
구현 복잡도를 낮추기 위해 서버리스 서비스를 끌어들일 수 있다.
방법2. 스프링 서버를 제거, 서버리스 아키텍처를 구성한다.
Cognito User Pools
로 인증한다. JWT를 내려받는다.Lambda
는 Cognito Federated Identity Pools
에게 토큰을 포워딩하고 AWS 크레덴셜을 얻는다.Lambda
는 PutObject를 할 타겟 s3 오브젝트 주소를 생성하고 PutObject
리퀘스트 명세를 생성한다. 이 명세를 AWS 크레덴셜로 서명하여 Sigv4 싸인을 만든다. PutObject
를 수행할 수 있다.그러나, 방법2은 스프링을 쓰지 않으니 이 레포에서 채용할 수 없다.
방법3. Cognito Federated Identity Pools
와 본인 스프링을 연동한다
Cognito Federated Identity Pools
에게 토큰을 포워딩하고 AWS 크레덴셜을 얻는다.PutObject
타깃이 될 S3 오브젝트 주소를 생성하고 PutObject
리퀘스트 명세를 작성한다. 이 명세를 AWS 크레덴셜로 서명하여 Sigv4 싸인을 만든다. 방법 2, 3에서 제3자가 URL과 Sigv4 싸인을 탈취한 상태라도, 사전 명세된 PutObject 요청을 알기 어려워 요청을 모사하기 힘들다.
이보다 더 엄격한 방식으로 특정 IP만 s3에 접근하도록 하는 법이 있다.
방법4. CloudFront Signed URL
을 내려주자
CloudFront
는 S3 버킷의 앞 단에 세워 연동할 수 있다.
CloudFront
는 S3와 비슷한 개념의 Signed URL를 제공할 수 있다. 이 URL의 경우 요청 User의 IP까지도 제한을 걸 수 있다.
개요
깃허브 이슈 작성 화면에서 이미지 파일을 드래그 & 드롭으로 업로드 하는 사용성을 흉내내 보자.
설계
User 사용성
https://127.0.0.1:8888
로 도달한다.Web Browser 관점
https://127.0.0.1:8888/s3_upload
에 멀티파트 업로드 요청을 보낸다.xsrf-token
헤더에 토큰을 동봉한다.Web Server 관점
https://127.0.0.1:8888/s3_upload
요청을 핸들링한다.@Part
로 업로드된 파일을 획득한다. 확장자를 취득한다. 파일에 대응하는uuid
를 만든다.s3://dragndrop-s3-upload/{user_id}/{uuid}.{ext}
에 파일을 업로드한다.https://dragndrop-s3-upload.s3.ap-northeast-1.amazonaws.com/{user_id}/{uuid}.{ext}
를 클라이언트로 내려 보낸다.Bucket 관점
x-amz-server-side-encryption
헤더가 있고 이 값이AES256
인 경우 PutObject 연산을 허용한다.