Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error 403 "CORS not enabled for bucket" when making OPTIONS request to manifest #436

Closed
jbaiter opened this issue Oct 5, 2023 · 6 comments
Assignees

Comments

@jbaiter
Copy link

jbaiter commented Oct 5, 2023

Request:

OPTIONS /api/cookbook/recipe/0068-newspaper/newspaper_issue_1-manifest.json HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Host: iiif.io
Origin: some-domain.tld
User-Agent: HTTPie/3.2.1

Response:

HTTP/1.1 403 Forbidden
Connection: keep-alive
Content-Length: 398
Date: Thu, 05 Oct 2023 22:31:17 GMT
Server: nginx/1.18.0
Via: 1.1 03d509e8374e9f42668961b5e0201348.cloudfront.net (CloudFront)
X-Amz-Cf-Id: NUvsdzztedC0zcUTuVv5uNoluZTBB5gsp6a8eSmoAKUrrA2HOZFTTQ==
X-Amz-Cf-Pop: FRA2-C2
X-Cache: Error from cloudfront

<html>
<head><title>403 Forbidden</title></head>
<body>
<h1>403 Forbidden</h1>
<ul>
<li>Code: AccessForbidden</li>
<li>Message: CORSResponse: CORS is not enabled for this bucket.</li>
<li>Method: OPTIONS</li>
<li>ResourceType: BUCKET</li>
<li>RequestId: YT8PSYTYEVHJXSFG</li>
<li>HostId: VF8G8U3d1hLH/aQnrrYIukklJwygjdsPfeDhgZn4XCD0tWLI+nkB3KbBhZHS91nlig+0mWNOxzc=</li>
</ul>
<hr/>
</body>
</html>

Given how important CORS is for IIIF, it would probably be wise to properly enable/implement it for cookbook resources and not only set the Access-Control-Allow-Origin header to *.

Background:
This error happens when making Content-Negotiation aware GET requests to resources, i.e. with an Accept header value that specifies the full JSON-LD MIME types for IIIF (see https://github.com/ProjectMirador/mirador/pull/3770/files#diff-166256fe28a89c78ada7b08488a3233671fc0511fd39d323c5cfc9433026e2a1R108-R112). These requests trigger a preflight OPTIONS request due to certain characters in the Accept header (more gnarly details in this comment: ProjectMirador/mirador#3770 (comment)).

@glenrobson glenrobson self-assigned this Oct 6, 2023
@glenrobson
Copy link
Member

I'm just working on this. I can get it working if you specify the following request header:

"Access-Control-Request-Method": "GET"

Is that a problem for you @jbaiter?

@ahankinson
Copy link

I think that would add an additional requirement on clients, and that would be more difficult to support across servers.

I have a common snippet of nginx configuration that I add to all IIIF servers now:

if ($request_method = OPTIONS) {
            add_header "Access-Control-Allow-Origin" '*';
            add_header "Access-Control-Allow-Methods" "GET, OPTIONS";
            add_header "Access-Control-Allow-Headers" "Accept,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
            add_header "Access-Control-Max-Age" 1728000;
            add_header "Content-Type" "text/plain; charset=utf-8";
            add_header "Content-Length" 0;
            return 204;
        }

This allows most servers to support OPTIONS requests without any additional requirements for clients to include in their request headers.

$ curl -vvvv -XOPTIONS https://iiif.rism.digital/info.json

@glenrobson
Copy link
Member

glenrobson commented Oct 19, 2023

Does it matter that the content type is wrong in your example? (text/plain rather than json)?

For info the way I've got it working at the moment its S3 thats throwing a 403 error without the method being specified:

<li>Code: AccessForbidden</li>
<li>Message: CORSResponse: This CORS request is not allowed. This is usually because the evalution of Origin, request method / Access-Control-Request-Method or Access-Control-Request-Headers are not whitelisted by the resource&#39;s CORS spec.</li>
<li>Method: OPTIONS</li>
<li>ResourceType: OBJECT</li>
<li>RequestId: XZGMAQDJS0PHZRKF</li>
<li>HostId: PuMH8I075lOGvwAheMvnx8OIP7+rHUKz133hCG2LV9YrCyR7SteMv4XKvvr4KM3gIbktkb8dXdE=</li>

I'm configuring it using:

https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html#cors-allowed-methods

which requires you to sepcify the allowed methods. Pull request:

IIIF/iiif-reverse-proxy-app#35

@glenrobson
Copy link
Member

OK I think I've fixed it so it doesn't require the request method. Its deploying now.

@ahankinson
Copy link

Does it matter that the content type is wrong in your example? (text/plain rather than json)?

The OPTIONS responses are empty, so it should send an empty body (Content-Length 0) and a 204 No Content response. In that case, it doesn't really matter what the Content-Type is.

@glenrobson
Copy link
Member

Thanks Andrew.

I've got it working like this:

curl -v -XOPTIONS https://iiif.io/api/cookbook/recipe/0068-newspaper/newspaper_issue_1-manifest.json -H "Origin: some-domain.tld" 
*   Trying 52.84.90.16:443...
* Connected to iiif.io (52.84.90.16) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=iiif.io
*  start date: Feb 11 00:00:00 2023 GMT
*  expire date: Mar 11 23:59:59 2024 GMT
*  subjectAltName: host "iiif.io" matched cert's "iiif.io"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
*  SSL certificate verify ok.
* using HTTP/2
* h2 [:method: OPTIONS]
* h2 [:scheme: https]
* h2 [:authority: iiif.io]
* h2 [:path: /api/cookbook/recipe/0068-newspaper/newspaper_issue_1-manifest.json]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* h2 [origin: some-domain.tld]
* Using Stream ID: 1 (easy handle 0x7f8299811400)
> OPTIONS /api/cookbook/recipe/0068-newspaper/newspaper_issue_1-manifest.json HTTP/2
> Host: iiif.io
> User-Agent: curl/8.1.2
> Accept: */*
> Origin: some-domain.tld
> 
< HTTP/2 204 
< access-control-allow-methods: GET
< access-control-allow-origin: *
< cache-control: public, no-transform, max-age=300
< date: Fri, 20 Oct 2023 13:18:58 GMT
< server: nginx/1.18.0
< vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< x-ua-compatible: IE=Edge,chrome=1
< x-cache: Miss from cloudfront
< via: 1.1 1f0b2edf1d5c127c320be20441fdb062.cloudfront.net (CloudFront)
< x-amz-cf-pop: LHR62-C4
< x-amz-cf-id: 2gRAv7YAiGQ1Nv-ovitdwycATBieewbM1JOI1bZyvWSMSYofjS3QGg==
< 
* Connection #0 to host iiif.io left intact

Let me know if there are any other issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants