교차 오리진 리소스 공유(CORS) 구성 - Amazon Simple Storage Service

교차 오리진 리소스 공유(CORS) 구성

CORS(Cross-origin 리소스 공유)는 한 도메인에서 로드되어 다른 도메인에 있는 리소스와 상호 작용하는 클라이언트 웹 애플리케이션에 대한 방법을 정의합니다. CORS 지원을 통해 Amazon S3으로 다양한 기능의 클라이언트 측 웹 애플리케이션을 구축하고, Amazon S3 리소스에 대한 Cross-Origin 액세스를 선택적으로 허용할 수 있습니다.

이 섹션에서는 Amazon S3 콘솔, Amazon S3 REST API 및 AWS SDK를 사용하여 CORS를 사용하는 방법을 보여줍니다. 교차 오리진 요청을 허용하도록 버킷을 구성하려면 해당 버킷에 CORS 구성을 추가합니다. CORS 구성은 버킷에 대한 액세스를 허용할 오리진과 각 오리진에 대해 지원되는 작업(HTTP 메서드) 그리고 기타 작업별 정보를 각각 식별하는 규칙과 기타 작업별 정보를 포함하는 문서입니다. S3 콘솔에서 CORS 구성은 JSON 문서여야 합니다.

JSON 및 XML의 CORS 구성 예제는 CORS 구성 섹션을 참조하십시오.

이 섹션에서는 Amazon S3 콘솔을 사용하여 S3 버킷에 CORS(Cross-Origin 리소스 공유) 구성을 추가하는 방법을 설명합니다.

버킷에 대해 CORS를 사용 설정하면 ACL(액세스 제어 목록)과 기타 액세스 권한 정책이 계속 적용됩니다.

중요

새 S3 콘솔에서 CORS 구성은 JSON이어야 합니다. JSON 및 XML의 CORS 구성 예제는 CORS 구성 섹션을 참조하십시오.

S3 버킷에 CORS 구성 추가
  1. AWS Management Console에 로그인한 후 https://console.aws.amazon.com/s3/에서 Amazon S3 콘솔을 엽니다.

  2. 버킷 목록에서 버킷 정책을 만들 버킷의 이름을 선택합니다.

  3. Permissions를 선택합니다.

  4. CORS(Cross-Origin 리소스 공유) 섹션에서 편집을 선택합니다.

  5. CORS 구성 편집기 텍스트 상자에 새 CORS 구성을 입력하거나 복사하여 붙여넣거나, 기존 구성을 편집합니다.

    CORS 구성은 JSON 파일입니다. 편집기에 입력하는 텍스트는 유효한 JSON이어야 합니다. 자세한 내용은 CORS 구성 단원을 참조하십시오.

  6. [변경 사항 저장(Save changes)]을 선택합니다.

    참고

    Amazon S3는 CORS 구성 편집기 제목 옆에 버킷의 Amazon 리소스 이름(ARN)을 표시합니다. ARN에 대한 자세한 내용은 Amazon 리소스 이름(ARN) 및 AWS 서비스 네임스페이스를 참조하십시오.

AWS SDK를 사용하여 버킷에 대한 cross-origin 리소스 공유(CORS)를 관리할 수 있습니다. CORS에 대한 자세한 내용은 교차 오리진 리소스 공유(CORS) 사용 섹션을 참조하십시오.

다음 예제를 고려하십시오.

  • CORS 구성을 만들고 버킷에 구성 설정

  • 구성을 검색하고 규칙을 추가하여 구성 수정

  • 버킷에 수정된 구성 추가

  • 구성 삭제

Java

실제 예제를 작성하여 테스트하는 방법에 대한 자세한 내용은 Amazon S3 Java 코드 예제 테스트 섹션을 참조하십시오.

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.BucketCrossOriginConfiguration; import com.amazonaws.services.s3.model.CORSRule; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class CORS { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; // Create two CORS rules. List<CORSRule.AllowedMethods> rule1AM = new ArrayList<CORSRule.AllowedMethods>(); rule1AM.add(CORSRule.AllowedMethods.PUT); rule1AM.add(CORSRule.AllowedMethods.POST); rule1AM.add(CORSRule.AllowedMethods.DELETE); CORSRule rule1 = new CORSRule().withId("CORSRule1").withAllowedMethods(rule1AM) .withAllowedOrigins(Arrays.asList("http://*.example.com")); List<CORSRule.AllowedMethods> rule2AM = new ArrayList<CORSRule.AllowedMethods>(); rule2AM.add(CORSRule.AllowedMethods.GET); CORSRule rule2 = new CORSRule().withId("CORSRule2").withAllowedMethods(rule2AM) .withAllowedOrigins(Arrays.asList("*")).withMaxAgeSeconds(3000) .withExposedHeaders(Arrays.asList("x-amz-server-side-encryption")); List<CORSRule> rules = new ArrayList<CORSRule>(); rules.add(rule1); rules.add(rule2); // Add the rules to a new CORS configuration. BucketCrossOriginConfiguration configuration = new BucketCrossOriginConfiguration(); configuration.setRules(rules); try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Add the configuration to the bucket. s3Client.setBucketCrossOriginConfiguration(bucketName, configuration); // Retrieve and display the configuration. configuration = s3Client.getBucketCrossOriginConfiguration(bucketName); printCORSConfiguration(configuration); // Add another new rule. List<CORSRule.AllowedMethods> rule3AM = new ArrayList<CORSRule.AllowedMethods>(); rule3AM.add(CORSRule.AllowedMethods.HEAD); CORSRule rule3 = new CORSRule().withId("CORSRule3").withAllowedMethods(rule3AM) .withAllowedOrigins(Arrays.asList("http://www.example.com")); rules = configuration.getRules(); rules.add(rule3); configuration.setRules(rules); s3Client.setBucketCrossOriginConfiguration(bucketName, configuration); // Verify that the new rule was added by checking the number of rules in the // configuration. configuration = s3Client.getBucketCrossOriginConfiguration(bucketName); System.out.println("Expected # of rules = 3, found " + configuration.getRules().size()); // Delete the configuration. s3Client.deleteBucketCrossOriginConfiguration(bucketName); System.out.println("Removed CORS configuration."); // Retrieve and display the configuration to verify that it was // successfully deleted. configuration = s3Client.getBucketCrossOriginConfiguration(bucketName); printCORSConfiguration(configuration); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } private static void printCORSConfiguration(BucketCrossOriginConfiguration configuration) { if (configuration == null) { System.out.println("Configuration is null."); } else { System.out.println("Configuration has " + configuration.getRules().size() + " rules\n"); for (CORSRule rule : configuration.getRules()) { System.out.println("Rule ID: " + rule.getId()); System.out.println("MaxAgeSeconds: " + rule.getMaxAgeSeconds()); System.out.println("AllowedMethod: " + rule.getAllowedMethods()); System.out.println("AllowedOrigins: " + rule.getAllowedOrigins()); System.out.println("AllowedHeaders: " + rule.getAllowedHeaders()); System.out.println("ExposeHeader: " + rule.getExposedHeaders()); System.out.println(); } } } }
.NET

실제 예제를 작성하여 테스트하는 방법에 대한 자세한 내용은Amazon S3 .NET 코드 예제 실행 단원을 참조하십시오.

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class CORSTest { private const string bucketName = "*** bucket name ***"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 s3Client; public static void Main() { s3Client = new AmazonS3Client(bucketRegion); CORSConfigTestAsync().Wait(); } private static async Task CORSConfigTestAsync() { try { // Create a new configuration request and add two rules CORSConfiguration configuration = new CORSConfiguration { Rules = new System.Collections.Generic.List<CORSRule> { new CORSRule { Id = "CORSRule1", AllowedMethods = new List<string> {"PUT", "POST", "DELETE"}, AllowedOrigins = new List<string> {"http://*.example.com"} }, new CORSRule { Id = "CORSRule2", AllowedMethods = new List<string> {"GET"}, AllowedOrigins = new List<string> {"*"}, MaxAgeSeconds = 3000, ExposeHeaders = new List<string> {"x-amz-server-side-encryption"} } } }; // Add the configuration to the bucket. await PutCORSConfigurationAsync(configuration); // Retrieve an existing configuration. configuration = await RetrieveCORSConfigurationAsync(); // Add a new rule. configuration.Rules.Add(new CORSRule { Id = "CORSRule3", AllowedMethods = new List<string> { "HEAD" }, AllowedOrigins = new List<string> { "http://www.example.com" } }); // Add the configuration to the bucket. await PutCORSConfigurationAsync(configuration); // Verify that there are now three rules. configuration = await RetrieveCORSConfigurationAsync(); Console.WriteLine(); Console.WriteLine("Expected # of rulest=3; found:{0}", configuration.Rules.Count); Console.WriteLine(); Console.WriteLine("Pause before configuration delete. To continue, click Enter..."); Console.ReadKey(); // Delete the configuration. await DeleteCORSConfigurationAsync(); // Retrieve a nonexistent configuration. configuration = await RetrieveCORSConfigurationAsync(); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } } static async Task PutCORSConfigurationAsync(CORSConfiguration configuration) { PutCORSConfigurationRequest request = new PutCORSConfigurationRequest { BucketName = bucketName, Configuration = configuration }; var response = await s3Client.PutCORSConfigurationAsync(request); } static async Task<CORSConfiguration> RetrieveCORSConfigurationAsync() { GetCORSConfigurationRequest request = new GetCORSConfigurationRequest { BucketName = bucketName }; var response = await s3Client.GetCORSConfigurationAsync(request); var configuration = response.Configuration; PrintCORSRules(configuration); return configuration; } static async Task DeleteCORSConfigurationAsync() { DeleteCORSConfigurationRequest request = new DeleteCORSConfigurationRequest { BucketName = bucketName }; await s3Client.DeleteCORSConfigurationAsync(request); } static void PrintCORSRules(CORSConfiguration configuration) { Console.WriteLine(); if (configuration == null) { Console.WriteLine("\nConfiguration is null"); return; } Console.WriteLine("Configuration has {0} rules:", configuration.Rules.Count); foreach (CORSRule rule in configuration.Rules) { Console.WriteLine("Rule ID: {0}", rule.Id); Console.WriteLine("MaxAgeSeconds: {0}", rule.MaxAgeSeconds); Console.WriteLine("AllowedMethod: {0}", string.Join(", ", rule.AllowedMethods.ToArray())); Console.WriteLine("AllowedOrigins: {0}", string.Join(", ", rule.AllowedOrigins.ToArray())); Console.WriteLine("AllowedHeaders: {0}", string.Join(", ", rule.AllowedHeaders.ToArray())); Console.WriteLine("ExposeHeader: {0}", string.Join(", ", rule.ExposeHeaders.ToArray())); } } } }

버킷에 CORS 구성을 설정하려면 AWS Management Console을 사용할 수 있습니다. 하지만 애플리케이션에서 요구할 경우 REST 요청을 직접 전송할 수도 있습니다. Amazon Simple Storage Service API 참조의 다음 섹션에서는 CORS 구성과 관련된 REST API 작업에 대해 설명합니다.