-
Notifications
You must be signed in to change notification settings - Fork 583
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
Conversation
…ion header instead of rejecting requests that didn't.
@@ -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")) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
2e5b184
to
3700169
Compare
3700169
to
9e93935
Compare
There was a problem hiding this 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.
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) { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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")) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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); | ||
} | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
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
14ebb44
to
8b90386
Compare
Using a client that supports request changes on redirect is a better option than a custom redirect handler. |
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.