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

The authorization header was not dropped by redirect strategy as expected. #5984

Closed
wants to merge 3 commits into from

Conversation

corneil
Copy link
Contributor

@corneil corneil commented Oct 15, 2024

Edit:
Discovered that RedirectStrategy was change from Apache HTTP Client 4 -> 5. The change meant header changes were not possible.
I copied to RedirectExec interceptor / chain handler and modified it to use the modified request instead of the original request to create a request builder.

…ion header instead of rejecting requests that didn't.
@corneil corneil requested a review from cppwfs October 15, 2024 12:29
@@ -68,7 +69,7 @@ public ResponseEntity<Map<String, String>> getBlobRedirect(@RequestHeader("Autho

@RequestMapping("/test/docker/registry/v2/blobs/test/data")
public ResponseEntity<Resource> getSignedBlob(@RequestHeader Map<String, String> headers) {
if (headers.containsKey("authorization")) {
if (!headers.containsKey("authorization")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why it worked in 2.11.x when the test said it should not contain authorized but now requires authorized?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is then how does the authorization header not get dropped?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

org.springframework.cloud.dataflow.container.registry.authorization.DropAuthorizationHeaderRequestRedirectStrategy doesn't reach the code to check if a header should be dropped.

Copy link
Contributor Author

@corneil corneil Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing org.apache.hc.client5.http.protocol.RedirectStrategy
to org.apache.http.client.RedirectStrategy
shows the return type change from HttpUriRequest to URI
So we will have to figure out where we can actually deal with the headers and if we need to actually drop the Authorization header.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial change I made was invalid and reversed.
The Authorization header should be dropped for most of the redirects on container queries.

@corneil corneil marked this pull request as draft October 15, 2024 15:43
@cppwfs cppwfs added this to the 3.0.x milestone Oct 16, 2024
@corneil corneil force-pushed the corneil/fix-registry-tests branch from 2e5b184 to 3700169 Compare October 16, 2024 13:29
@corneil corneil changed the title The registry stub was incorrectly rejecting requests that contained an authorization header. The authorization header was not dropped by redirect strategy as expected. Oct 16, 2024
@corneil corneil requested review from cppwfs and rstoyanchev October 16, 2024 13:30
@corneil corneil force-pushed the corneil/fix-registry-tests branch from 3700169 to 9e93935 Compare October 16, 2024 13:34
@corneil corneil marked this pull request as ready for review October 16, 2024 13:47
@corneil corneil requested review from onobc and removed request for rstoyanchev October 16, 2024 14:36
Copy link

@rstoyanchev rstoyanchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't comment on the solution, but it's worth reaching out through one of the channels on https://hc.apache.org/get-involved.html, mailing list or issue tracker. There may be related issues and discussions there as well.

@onobc
Copy link
Contributor

onobc commented Oct 16, 2024

This is on the mailing list here w/ 3 options.

@corneil
Copy link
Contributor Author

corneil commented Oct 16, 2024

This is on the mailing list here w/ 3 options.

I will look into a chain handler that strips the header if I can consistently figure out that we are handling a redirect.

}
}
} catch (URISyntaxException e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice cleanup!

@@ -32,9 +35,11 @@

/**
* @author Adam J. Weigold
* @author Corneil du Plessis
*/
@RestController
public class S3SignedRedirectRequestController {
Copy link
Contributor

@onobc onobc Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[UNRELATED-TO-YOUR-CHANGES] These 2 controllers are terribly named and there is no comment telling us that these are test controllers used to mimic what S3 signed redirects look like.

Because it is a test, we do not need to instrument it w/ log statements to debug. In that case, we can just walk through it in a debugger. Do you mind removing these debugging log statements?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -68,7 +69,7 @@ public ResponseEntity<Map<String, String>> getBlobRedirect(@RequestHeader("Autho

@RequestMapping("/test/docker/registry/v2/blobs/test/data")
public ResponseEntity<Resource> getSignedBlob(@RequestHeader Map<String, String> headers) {
if (headers.containsKey("authorization")) {
if (!headers.containsKey("authorization")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be removed as it is expected that the auth header has been removed. Same as the other S3 test controller thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 98 to 99
try {
if (isHeadMethod(method)) {
return new HttpHead(httpUriRequest).getUri();
}
else {
return new HttpGet(httpUriRequest).getUri();
}
}
catch (URISyntaxException e) {
throw new HttpException("Unable to get location URI", e);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines are repeated in all 3 cases. Let's factor this out for DRY.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

DropAuthorizationHeaderRequestRedirectStrategy redirectStrategy = new DropAuthorizationHeaderRequestRedirectStrategy(extra);
HttpComponentsClientHttpRequestFactory customRequestFactory = new HttpComponentsClientHttpRequestFactory(
clientBuilder.setRedirectStrategy(redirectStrategy)
.replaceExecInterceptor(ChainElement.REDIRECT.name(), new SpecialRedirectExec(routePlanner, redirectStrategy))
Copy link
Contributor

@onobc onobc Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on your reply to the mailing list comment, it sounds like you are going to pursue option 2) which is to append a custom request interceptor immediately after RedirectExec and strip undesired headers from requests.

I appreciate the scrappiness of figuring out how to get this to work in this case but I would really really like to NOT own this copy of the SpecialRedirectExec as we do not have tests for it, it is immediately out of date as soon as we commit it to this repo, and so on so forth the cost of copy/pasta/patch approach. I did find this test example in httpclient around adding interceptors (may or may not be helpful).

https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientInterceptors.java

Copy link
Contributor Author

@corneil corneil Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a lot of back and forth with extra exec interceptor and request interceptor the only conclusion I have is that we need a modified version of RedirectExec that makes it possible to remove the header in the RedirectStrategy
There is not other way to get involved in the redirect process that doing exactly what RedirectExec does.

Copy link
Contributor

@onobc onobc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this @corneil . It is definitely a hairy section of the codebase and http client 4->5 has changed quite a bit. I do have some concerns/suggestions.

@corneil corneil marked this pull request as draft October 17, 2024 08:56
@corneil corneil requested review from onobc and rstoyanchev October 17, 2024 11:23
Remove comments from test controller.
Reverted ContainerRegistryService
Add SpecialRedirectExec to replace RedirectExec.
Ensure DropAuthorizationHeaderRequestRedirectStrategy changes request headers used to create the redirect request.

Fixes spring-cloud#5989
@corneil corneil force-pushed the corneil/fix-registry-tests branch from 14ebb44 to 8b90386 Compare October 17, 2024 11:55
@corneil corneil marked this pull request as ready for review October 17, 2024 11:55
@corneil corneil marked this pull request as draft October 21, 2024 08:59
@corneil
Copy link
Contributor Author

corneil commented Oct 24, 2024

Using a client that supports request changes on redirect is a better option than a custom redirect handler.

@corneil corneil closed this Oct 24, 2024
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

Successfully merging this pull request may close these issues.

4 participants