-
Notifications
You must be signed in to change notification settings - Fork 39
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
Update headers in do_request method, provider.py #129
Conversation
During the push operation POST and PUT methods loose provided auth headers. It is crucial for remote registry, since further re-auth logic tries to reach registry locally. do_request method is updated to include always 'Authorization' header if it is provided. Signed-off-by: my5cents <[email protected]>
oras/provider.py
Outdated
@@ -893,6 +893,7 @@ def do_request( | |||
:type stream: bool | |||
""" | |||
headers = headers or {} | |||
headers.update(self.headers) |
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 should likely be tried after an initial failure (e.g., see below where it updates after the auth response.
I think the maintain the current behavior we might want to have a boolean that determines if the headers should be re-used and persist (or not).
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 quick reply!
After initial failure it tries to get token from realm returned in 'www-authenticate' header, but remote registry does not expose it externally, and all the following re-auth attempts fail since URL 'https://docker-registry-realm' is not available.
We can pass refresh_headers flag with False value to keep self.headers in request, like it is done in the pull method. But my concerns here are:
- it is necessary to pass it through long chain (push -> upload_blob -> put_upload/chunked_upload);
- if user performed explicit login/set_basic_auth operation, then he meant to use the credentials until he calls logout operation
What do you think?
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 normal flow I think is to expect that auth flow to work, although now that I think of it the auth isn't standardized. The basic auth is usually there to then request the token (the flow we have).
I understand your use case I think, and perhaps we need another set credential function that sets something permanently and does not try the auth flow?
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.
self.headers property seems quite permanent :) It is accessible from all Registry methods although is not actually used in each request...
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.
If you have a set method for more static credentials, that would add those credentials to the headers, and given the client knows that set method was used, it would not touch or try to update headers.
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.
That was my initial point, basic auth (username and pass) are static unlike the token and could be used in all requests until the explicit logout (like in ORAS CLI).
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.
But that function is used to encode in the initial request for the token. Saying to take the basic auth and not use it for a token (just provide as is) is a different flow I think.
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 see. Fixed in following commit to propagate refresh_headers flag like in pull flow.
I guess, refresh_headers flag may be turned later to the internal property, and set automatically within set_token_auth method to True and within the set_basic_auth method to False.
Added refresh_headers flag to allow user to keep basic auth in headers during the push flow Signed-off-by: my5cents <[email protected]>
This looks good - you are exposing this variable to more functions. Could you please bump the version (in version.py) and add a line to CHANGELOG.md? For the formatting/linting errors you can see the issue in the GitHub action output and run the same versions (e.g., black) locally to fix. |
Signed-off-by: my5cents <[email protected]>
Signed-off-by: my5cents <[email protected]>
Signed-off-by: my5cents <[email protected]>
Done |
@my5cents looks like you just need one more run of black and we're good (take note of the version). |
Signed-off-by: Yuriy Novostavskiy <[email protected]>
This reverts commit 598f6b0. Signed-off-by: Yuriy Novostavskiy <[email protected]>
Signed-off-by: Yuriy Novostavskiy <[email protected]>
I reformatted remaining part, it should be fine |
I work with remote registry, available via http URL. I set basic auth and tried to do some operations within ORAS. I was able to get tags, manifest and make pull, but push operation failed. Debugging showed that during the push operation POST and PUT methods loose provided auth headers. It is crucial for remote registry, since further re-auth logic tries to reach registry locally. Below is my log and truncated stack trace (it's too long):
If do_request method is updated to include provided 'Authorization' header, push works fine as well as other operations: