Implement login with private registry#1564
Conversation
|
this fixes #1357 |
|
@samalba please have a look |
|
Thanks Marco for the contribution, it looks really good. I'll have a closer look today, especially to test it. cc @shin- |
|
Played around with this one at some length; looks like there's still a couple of warts:
Basically, could use a bit more polishing + test cases. But with the right incantations it seems to work. |
|
@avaer Thank you for pointing out theese corner cases. I've updated the commit to cover theses issues. |
|
Cool, seems to be working as advertised now. Eagerly waiting for this in mainline :). |
|
Looks good, I think it would also be useful to support this: |
|
While i think that its better to support only well defined formats, I see that a user might run into that case. |
registry/registry.go
Outdated
There was a problem hiding this comment.
What is this magic number 9?
There was a problem hiding this comment.
to test if the url has a path it is significant if it has a / after 'http://' or 'https://' which is the 8th char.
I personally think that doing tricks to urls is mostly wrong. So the implementation was originally only handling the two most significant cases:
- Full URL
- Prefix format
Though shin- has a point, that users might just do that and wonder.
|
I updated the commit to rebase and fix a bug with the way I transfer the authConfig to the docker api. |
|
Hey, I think you're misisng an import in api.go :( |
|
@shin- thanks, made an error during rebase/merge. its fixed now. |
|
Alright, LGTM 👍 |
|
@mhennings any particular reason to pass the authConfig via parameter in Maybe we could add parameter support in |
|
@vieux it had to be passed as a parameter because the same api endpoint is used for docker import - < xyz.tar If you like to move the authConfig on postImagePush into a parameter I can do that. |
|
@vieux Ok, ive moved the parameter I've also rebased and made sure LoadConfig is called, as that PR went in in the meantime |
|
The last change you see here does two things:
To make it easer to keep track of these small additons i've started to put commits on top |
api.go
Outdated
There was a problem hiding this comment.
Why are you base64 encoding entire JSON object? Why would you not pass authentication data via the Authentication header?
There was a problem hiding this comment.
I'm not sure having the authConfig data in an Authentication header is the best idea -- the header implies that you're authenticating to the API itself. Here, we're passing auth data that will be used by the API further down the line to perform certain operations, so I like the idea of having it as a parameter better.
There was a problem hiding this comment.
@shin- Is there a good reason to base64 the entire json obj?
There was a problem hiding this comment.
Encoding the full object is the way it was done before and i do not see a reason to change that.
The only difference is that it is now a parameter because it would conflict as the body.
if i replace that with a pseudo basic auth i would create new problems
- not all relevant parameters are transfered (server address is needed)
- future changes to enable stronger auth would be restricted without need
- the code becomes incompatible to current api
- users could expect full basic auth behaviour which is not intended at these routes
encoding as base64 is required to be url safe
There was a problem hiding this comment.
@mhennings I don't get why you say Encoding the full object is the way it was done before,
you added "encoding/base64" yourself, before it was simply sent has body.
There was a problem hiding this comment.
It was not encoded as base64 but sent as a full json object in the body of the request of the "push" part.
There was no authentication during pull.
I understood the question to be regarding sending a full object instead of a basic auth header.
There was a problem hiding this comment.
the base64 is fine AFAIC. URL-encoding a JSON dict would get ugly really fast.
|
If there are questions open i would be happy if we could resolve them. If not -- maybe we could merge this? Kind regards, Marco |
|
I'm a bit confused on why you need the "server address" field in the authConfig. Isn't this redundant information? |
|
@kyleconroy This is because the ~/.dockerconfig file is read by the client process and not the docker daemon. When doing a pull or push the server address is taken from the repository prefix (so this also remains as it is now). Hope this helps understanding the changes. |
|
The http header changes of @shin- are merged, and the changeset was rebased. (the history is long, because i did a full cherry-pick to ease the rebase) |
|
@shin- I think you should keep support for body in It's a big change, it break compat. |
|
Yep, I was thinking about that. Let's bump the API version to 1.5 and include this change + #1701 |
|
Great |
|
@mhennings Can you please rebase your changes? |
To improve the use of docker with a private registry the login command is extended with a parameter for the server address. While implementing i noticed that two problems hindered authentication to a private registry: 1. the resolve of the authentication did not match during push because the looked up key was for example localhost:8080 but the stored one would have been https://localhost:8080 Besides The lookup needs to still work if the https->http fallback is used 2. During pull of an image no authentication is sent, which means all repositories are expected to be private. These points are fixed now. The changes are implemented in a way to be compatible to existing behavior both in the API as also with the private registry. Update: - login does not require the full url any more, you can login to the repository prefix: example: docker logon localhost:8080 Fixed corner corner cases: - When login is done during pull and push the registry endpoint is used and not the central index - When Remote sends a 401 during pull, it is now correctly delegating to CmdLogin - After a Login is done pull and push are using the newly entered login data, and not the previous ones. This one seems to be also broken in master, too. - Auth config is now transfered in a parameter instead of the body when /images/create is called.
|
Done. There where some minor merges. I have tested that it still works. |
|
@mhennings does this change mean I can run my own docker-registry and force people to authenticate for both pull and push? (I want people to authenticate when pulling images from my registry). |
|
@aslakhellesoy Please note that you need to setup basic auth on the server side, too. |
|
@mhennings, you said to _aslakhellesoy - "Yes, pull and push can use authentication. ... you need to setup basic auth on the server side, too." Have you successfully authenticated and pushed/pulled using basic auth? Your changes only enabled a custom index for auth, right? I'm asking because I've tried and tried using basic auth, with no luck. Please see also docker-archive/docker-registry#82 (comment) Does anyone have a full example of how to use basic auth with a private registry? That'd be awesome. |
|
@lukewpatterson in theory it can be done by a proxy the handles basic auth. after thinking about it it seems more realistic to implement it inside the open sourced registry. |
To improve the use of docker with a private registry the login
command is extended with a parameter for the server address.
While implementing i noticed that two problems hindered authentication to a
private registry:
the resolve of the authentication did not match during push
because the looked up key was for example localhost:8080 but
the stored one would have been https://localhost:8080
Besides The lookup needs to still work if the https->http fallback
is used
During pull of an image no authentication is sent, which
means all repositories are expected to be private.
These points are fixed now. The changes are implemented in
a way to be compatible to existing behavior both in the
API as also with the private registry.
Update:
login does not require the full url any more, you can login
to the repository prefix:
example:
docker logon localhost:8080
Fixed corner corner cases:
not the central index
CmdLogin
and not the previous ones. This one seems to be also broken in master, too.
/images/create is called.