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

CORS policy issue when retrieving bitstream through Angular #2962

Closed
jonas-atmire opened this issue Sep 10, 2020 · 3 comments
Closed

CORS policy issue when retrieving bitstream through Angular #2962

jonas-atmire opened this issue Sep 10, 2020 · 3 comments
Labels
bug e/0 Estimate in hours
Milestone

Comments

@jonas-atmire
Copy link
Contributor

jonas-atmire commented Sep 10, 2020

Describe the bug
During the implementation of the Angular counterpart of the scripts and processes output, @MarieVerdonck noticed the following error when retrieving the output bitstream through a GET call of the relevant process._links.output.href link

Access to XMLHttpRequest at 'http://localhost:8080/server/api/core/bitstreams/fd4bf164-a876-486d-95a6-d9f24cb23700/content?authentication-token=eyJhbGciOiJIUzI1NiJ9.eyJlaWQiOiJjZDgyNGE2MS05NWJlLTRlMTYtYmNjZC01MWZlYTI2NzA3ZDAiLCJzZyI6W10sImV4cCI6MTU5OTcyNzMzOH0.s3EVCgQjjw1dLq2auJnDCzhb6ze59LxDYgEeX6tHHw0' from origin 'http://localhost:4000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This LOOKS to be CORS related at a first glance, but might need additional investigation as well.
Request

curl --location --request GET 'http://localhost:8080/server/api/core/bitstreams/fd4bf164-a876-486d-95a6-d9f24cb23700/content' \
--header 'Authorization: Bearer {{currentAccessToken}}'

Response headers:
Screenshot 2020-09-10 at 11 31 53

This might be solvable if the CORS headers are properly set through the REST Api, it might also have another underlying issue that is not readily apparent.

To Reproduce
Steps to reproduce the behaviour:

  1. Setup REST PR
  2. Setup Angular PR
  3. Make sure to trigger a script that keeps output in a file.
  4. Try to download that particular output bitstream

Expected behaviour
The bitstream should be properly 'downloaded', no CORS error should be logged, and the information of the logs should be shown in the UI

Related work
#2934
DSpace/dspace-angular#827

@jonas-atmire jonas-atmire added bug needs triage New issue needs triage and/or scheduling labels Sep 10, 2020
@tdonohue
Copy link
Member

tdonohue commented Sep 10, 2020

@jonas-atmire and @MarieVerdonck : I've looked at this a bit today, and it looks like the backend code to download Bitstreams is completely bypassing Spring Security (and writing its own custom response). This is why none of the CORS headers are returned (as those are dynamically inserted into the response by Spring Security).

The /bitstreams/[uuid]/content path is using BitstreamRestController, which in turn is using a custom MultipartFileSender.

To me, the problem looks like it's with the MultipartFileSender, which bypasses Spring classes (like HttpHeader or ResponseEntity<InputStreamResource>) and directly modifies/changes the HttpServletResponse, changing all the Headers & piping the content to it directly. Looking around, it looks like this class was borrowed/copied from this StackOverflow answer: https://stackoverflow.com/a/28479001

Later in that exact same StackOverflow question it's noted that Spring Boot now is able to handle similar Range requests automatically on its own: https://stackoverflow.com/a/63393094 (And I found a similar answer here https://stackoverflow.com/a/54615714 which links back to the internal code in Spring to manage sending back partial content from a Resource).

So, my suspicion is the behavior seen from Angular is because this one endpoint is not using any standard Spring tooling. We'd either need to work to update this based on Spring Boot (i.e. perhaps gutting or removing much of the logic of MultipartFileSender), or we'd need to find a way to update MultipartFileSender to respect/use the CORS (and perhaps other) headers that Spring Security sets automatically. I'm not sure offhand which direction is better, though I'd have a slight preference towards seeing if Spring Boot can support the necessary Range requests we require...and therefore moving to using it instead of a custom solution.

For completion, the reason I think this is endpoint specific is the following:

  1. I cannot reproduce this same behavior on other endpoints. For example curl -v 'http://localhost:8080/server/api/core/collections' -H 'Origin: http://localhost:4000' will return the Access-Control-Allow-Origin: http://localhost:4000 header as expected
  2. However, using curl, I notice that this /content path does NOT return the same headers. The request I'm trying is curl -v 'http://localhost:8080/server/api/core/bitstreams/e2b70c0a-4403-490c-96a2-db2bc6e126f5/content' -H 'Origin: http://localhost:4000' -H 'Authorization: Bearer [token]'

@tdonohue tdonohue added this to To Do in DSpace 7 Beta 5 via automation Sep 24, 2020
@tdonohue tdonohue added this to the 7.0beta5 milestone Sep 24, 2020
@tdonohue tdonohue added e/0 Estimate in hours and removed needs triage New issue needs triage and/or scheduling labels Sep 24, 2020
@tdonohue
Copy link
Member

I've created a new ticket #2983 to describe what must be done to fix this issue. This work will be scheduled for beta5.

I've added an estimate of 0 hours to this ticket as the estimate for this work will be defined in #2983

@benbosman
Copy link
Member

Replaced by #2983

DSpace 7 Beta 5 automation moved this from To Do to Done Oct 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug e/0 Estimate in hours
Projects
No open projects
Development

No branches or pull requests

3 participants