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

Can't sign-in to Generic Docker Registries #2735

Closed
minjatJ opened this issue Feb 25, 2021 · 9 comments · Fixed by #2813
Closed

Can't sign-in to Generic Docker Registries #2735

minjatJ opened this issue Feb 25, 2021 · 9 comments · Fixed by #2813

Comments

@minjatJ
Copy link

minjatJ commented Feb 25, 2021

Hello vscode-docker team!
First of all thanks for the great work!

My Setup (From VSCode About)

Version: 1.53.2
Commit: 622cb03f7e070a9670c94bae1a45d78d7181fbd4
Date: 2021-02-11T11:48:44.518Z
Electron: 11.2.1
Chrome: 87.0.4280.141
Node.js: 12.18.3
V8: 8.7.220.31-electron.0
OS: Linux x64 5.4.0-65-generic  (Ubuntu 20.04.2 LTS)
ms-azuretools.vscode-docker: v1.10.0

Issue

I am trying to add 2 Generic docker registries without any success.

  • The 1st registry is managed by a self-hosted Gitlab setup. I am able add the registry (Through "Connect Registry"/"Generic Docker Registry") but when trying to list it, the following error appears: Error: Failed with code "404"
  • The 2nd registry is managed by a self-hosted Portus setup. The same error happens.

After some research and going through my registries logs I might have found out the issue: When asking for a token through the realm Gitlab and Portus only handles GET HTTP requests while vscode-docker is using the method POST (See: https://github.com/microsoft/vscode-docker/blob/main/src/tree/registries/auth/BasicOAuthProvider.ts#L23-L33).

Logs

The working requests were issued by docker login command while the others were triggered when listing registries in vscode-docker extension.

Gitlab
// POST /jwt/auth endsup with 404
x.x.x.x - AUsername [25/Feb/2021:14:37:34 +0100] "POST /jwt/auth HTTP/1.1" 404 34 "-" "-"

// GET /jwt/auth endsup with 200
x.x.x.x - AUsername [25/Feb/2021:14:38:03 +0100] "GET /jwt/auth?account=AUsername&client_id=docker&offline_token=true&service=container_registry HTTP/1.1" 200 241 "-" "SomeAgent"
Portus
// GET /v2/token endsup with a 200
8c4258f1f0ce_portus_portus_1 | Started GET "/v2/token?account=AUsername&client_id=docker&offline_token=true&service=registry.someurl" for x.x.x.x at 2021-02-25 13:50:00 +0000
...
8c4258f1f0ce_portus_portus_1 | Completed 200 OK in 392ms (Views: 1.8ms | ActiveRecord: 58.8ms)

// POST /v2/token endsup with 404
8c4258f1f0ce_portus_portus_1 | Started POST "/v2/token" for x.x.x.x at 2021-02-25 11:11:26 +0000
8c4258f1f0ce_portus_portus_1 | ActionController::RoutingError (No route matches [POST] "/v2/token"):

What's next?

Do you have any suggestion on how to handle this by any chance? Docker registry specs don't really specify which HTTP method should be used for the /v2/token endpoint so I guess there is no right or wrong implementation.

I can create a PR to change the call from POST to GET if needed.

Thanks for your time!
Joris

@bwateratmsft
Copy link
Collaborator

Good to know. It's tough because some of the registries do require POST, not GET. Maybe we could implement a fallback from one to the other?

@minjatJ
Copy link
Author

minjatJ commented Mar 1, 2021

Alright, I see. I can't see a cleaner solution than the fallback. It's such a shame Gitlab and Portus don't use a 405 Method Not Allowed.

@dbreshears dbreshears added this to the 1.12.0 milestone Mar 3, 2021
@bwateratmsft
Copy link
Collaborator

Hm, this might be more complicated than I first thought. Our auth flow in the generic case is this:

  1. Request a resource, using basic auth (with the username/password the user provided when connecting the registry)
  2. If that fails with 401 and has a 'www-authenticate' header, look for the realm, service, and scope from there
  3. Make a POST request to that realm with the same basic auth as (1) above, with grant_type = password, the service, and the scope as form input, and hopefully what we get back has a token field
  4. Repeat (1) but with the bearer token from (3)
  5. In the future, we can skip step (1) because we have already obtained a realm, service, and scope to request against before, so go straight to (3)

@minjatJ do you know if the providers you gave as examples accept basic auth to get the token from the realm endpoint?

@minjatJ
Copy link
Author

minjatJ commented Mar 18, 2021

Hi @bwateratmsft
From what I can see in Portus test spec it's using Basic Auth to get a token api/v2/token_spec.rb
As for Gitlab here is from the doc auth/jwt.md

The token server should first attempt to authenticate the client using any authentication credentials provided with the request. As of Docker 1.8, the registry client in the Docker Engine only supports Basic Authentication to these token servers

So in short YES I believe both providers (If not ALL providers) accept basic auth to get the token (As it's what docker clients should use in any case)

@bwateratmsft
Copy link
Collaborator

@minjatJ I went ahead with the approach of trying POST first and GET if that fails. Certainly there are still cases where this won't work either--typically if auth happens in any other nonstandard way (which seems to be the standard 🤷‍♂️).

For #869 / #2033 we plan on making a fully-fledged extensibility API for registries. This would allow users to contribute extensions that would be able to authenticate to and use any registry they implement for.

@bwateratmsft bwateratmsft removed their assignment Mar 25, 2021
@bwateratmsft bwateratmsft removed the P2 label Mar 25, 2021
@minjatJ
Copy link
Author

minjatJ commented Mar 25, 2021

Awesome, you're a champ @bwateratmsft ! Can't wait to test that

@bwateratmsft
Copy link
Collaborator

This change is now released with Docker extension version 1.12.0.

@minjatJ
Copy link
Author

minjatJ commented Apr 14, 2021

Hi @bwateratmsft thanks!

Just tested 1.12.1 but it looks like fetch is throwing the following "Error: Request with GET/HEAD method cannot have body" so the GET request is not even fired !-_- (See: whatwg/fetch#551).

I can create a PR to remove form from options and add those values as URL param when entering https://github.com/microsoft/vscode-docker/blob/main/src/tree/registries/auth/BasicOAuthProvider.ts#L42

What do you think?

@bwateratmsft
Copy link
Collaborator

Yeah, go ahead and open a PR. Ultimately, we're going to need #2033 to really handle the multitude of registries well.

@vscodebot vscodebot bot locked and limited conversation to collaborators May 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants