cesanta / docker_auth

Authentication server for Docker Registry 2
Apache License 2.0
1.28k stars 305 forks source link

Trouble getting refresh_token using OAuth2 #313

Open ghost opened 3 years ago

ghost commented 3 years ago

I am following the documentation (https://github.com/distribution/distribution/blob/main/docs/spec/auth/oauth.md) to try and get a refresh_token when using the cesanta/docker_auth:1 image.

The request is this:

curl --location --request POST 'https://(company website):2087/auth' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'service=company-token-service' \
--data-urlencode 'client_id=fooclient' \
--data-urlencode 'access_type=offline' \
--data-urlencode 'username=myuser' \
--data-urlencode 'password=mypwd'

and the response:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjRCRzY6RjRQMjpPSFNJOlpESU46RzVENTpFQlIyOkkyRjQ6UDJJQTpCRklMOlRZRjI6M1JGUjpYRzZLIn0.eyJpc3MiOiJwZWZpLXRva2VuLWlzc3VlciIsInN1YiI6InBsZyIsImF1ZCI6InBlZmktdG9rZW4tc2VydmljZSIsImV4cCI6MTYyODA4NTc0NSwibmJmIjoxNjI4MDg0ODM1LCJpYXQiOjE2MjgwODQ4NDUsImp0aSI6Ijc2ODgyNTg3NDU2NTkwNDcyNzUiLCJhY2Nlc3MiOltdfQ.Qfp31vBooPIQT27Yl55bolbZbsY4RfOOYfkyoCPQqx8F6B2yX8flzq1byIAlkkcy7mKwvqUtF2DriiMd633MXLO_ZRfRE1rjE1BOZgA_lXPJ3Iz-5shMucYQY2Dxuq7gK2lnr-FGoB4YPNTFIxAnjDo2TQ4m4a0xTwhqvx_VC-chxgHzpQpOMyQSgCZ8Uvp0DxQd7Z4FfDx8dqKsU0ToGzA0Q2URzIacVQ8X27wFsNXacupAUDN59LCLHttLW90Ujb_dB5fHUXx3KkJffzw1paqeUmF3bxdFJgBk9cdboerCYSCImuDROkhHUTW3kt0TN_vXkzDu2TDrXayARw2oTg",
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjRCRzY6RjRQMjpPSFNJOlpESU46RzVENTpFQlIyOkkyRjQ6UDJJQTpCRklMOlRZRjI6M1JGUjpYRzZLIn0.eyJpc3MiOiJwZWZpLXRva2VuLWlzc3VlciIsInN1YiI6InBsZyIsImF1ZCI6InBlZmktdG9rZW4tc2VydmljZSIsImV4cCI6MTYyODA4NTc0NSwibmJmIjoxNjI4MDg0ODM1LCJpYXQiOjE2MjgwODQ4NDUsImp0aSI6Ijc2ODgyNTg3NDU2NTkwNDcyNzUiLCJhY2Nlc3MiOltdfQ.Qfp31vBooPIQT27Yl55bolbZbsY4RfOOYfkyoCPQqx8F6B2yX8flzq1byIAlkkcy7mKwvqUtF2DriiMd633MXLO_ZRfRE1rjE1BOZgA_lXPJ3Iz-5shMucYQY2Dxuq7gK2lnr-FGoB4YPNTFIxAnjDo2TQ4m4a0xTwhqvx_VC-chxgHzpQpOMyQSgCZ8Uvp0DxQd7Z4FfDx8dqKsU0ToGzA0Q2URzIacVQ8X27wFsNXacupAUDN59LCLHttLW90Ujb_dB5fHUXx3KkJffzw1paqeUmF3bxdFJgBk9cdboerCYSCImuDROkhHUTW3kt0TN_vXkzDu2TDrXayARw2oTg"
}

No refresh_token. Here's the docker output:

auth           | I0804 13:47:25.277643       1 server.go:412] Request: &{Method:POST URL:/auth Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Accept:[*/*] Accept-Encoding:[gzip] Cache-Control:[no-cache] Cdn-Loop:[cloudflare] Cf-Connecting-Ip:[199.36.223.53] Cf-Ipcountry:[CA] Cf-Ray:[67983ccacd124bbf-YUL] Cf-Visitor:[{"scheme":"https"}] Connection:[Keep-Alive] Content-Length:[115] Content-Type:[application/x-www-form-urlencoded] Cookie:[PHPSESSID=s0csatkavj9470t32npdhhfve8] Postman-Token:[314bdd0c-25f2-4bc1-a4bf-7df3fa9a0adb] User-Agent:[PostmanRuntime/7.28.1] X-Forwarded-For:[199.36.223.53] X-Forwarded-Proto:[https]] Body:0xc000588100 GetBody:<nil> ContentLength:115 TransferEncoding:[] Close:false Host:(company):2087 Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr:(company ip):12194 RequestURI:/auth TLS:0xc000586000 Cancel:<nil> Response:<nil> ctx:0xc000588140}
auth           | I0804 13:47:25.277916       1 server.go:456] Auth request: {myuser:***@(company ip):12194 []}
auth           | I0804 13:47:25.283252       1 server.go:295] Authn static myuser -> true, map[], <nil>
auth           | I0804 13:47:25.294541       1 server.go:407] New token for {myuser:***@(company ip):12194 []} map[]: {"iss":"company-token-issuer","sub":"myuser","aud":"company-token-service","exp":1628085745,"nbf":1628084835,"iat":1628084845,"jti":"7688258745659047275","access":[]}
auth           | I0804 13:47:25.294603       1 server.go:492] {"access_token":"(token above)"}

docker-compose.yml:

version: "3.5"

services:
  registry:
    restart: always
    image: registry:2
    container_name: registry
    ports:
      - 8443:443
    environment:
      REGISTRY_HTTP_ADDR: 0.0.0.0:443
      REGISTRY_HTTP_TLS_CERTIFICATE: /certs/bundle.crt
      REGISTRY_HTTP_TLS_KEY: /certs/company.key
      REGISTRY_AUTH_TOKEN_REALM: https://(company):2087/auth
      REGISTRY_AUTH_TOKEN_SERVICE: company-token-service
      REGISTRY_AUTH_TOKEN_ISSUER: company-token-issuer
      REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /certs/bundle.crt
    volumes:
      - /home/myuser/certs:/certs
      - /home/myuser/docker-registry/data:/var/lib/registry

  docker_auth:
    restart: always
    image: cesanta/docker_auth:1
    container_name: auth
    ports:
      - 2087:2087
    volumes:
      - /home/myuser/docker-registry:/config:ro
      - /var/log/docker_auth:/logs
      - /home/myuser/certs:/certs
    command: --v=4 -log_dir /logs -alsologtostderr /config/auth_config.yml

auth_config.yml:

server:
  addr: ":2087"
  certificate: "/certs/bundle.crt"
  key: "/certs/(company).key"
token:
  issuer: "company-token-issuer"  # Must match issuer in the Registry config.
  expiration: 900
users:
  "myuser":
    password: "$2y$05$dHqSnejfhOycqL4FixW.Nu.HDftwQU7iuNyzdDs6/qK7.M9PfvZ9i"
  "": {} # anonymous
acl:
  - match: {account: "myuser"}
    actions: ["*"]
  - match: {account: ""}
    actions: ["pull"]

In addition, with the config above with anonymous access, I seem to receive the same access_token/token regardless of the POST parameters (even without parameters at all). Because of this, if I send a POST with grant_type=refresh_token and refresh_token=(random garbage), I still receive the access_token and no check seems to be done. Example request, response and docker output in that case: curl --location --request POST 'https://(company):2087/auth

{
    "access_token": "(the token)",
    "token": "(the token)"
}
auth           | I0804 14:02:39.065846       1 server.go:412] Request: &{Method:POST URL:/auth Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Accept:[*/*] Accept-Encoding:[gzip] Cache-Control:[no-cache] Cdn-Loop:[cloudflare] Cf-Connecting-Ip:[199.36.223.53] Cf-Ipcountry:[CA] Cf-Ray:[67985319e8014bbf-YUL] Cf-Visitor:[{"scheme":"https"}] Connection:[Keep-Alive] Content-Length:[0] Cookie:[PHPSESSID=s0csatkavj9470t32npdhhfve8] Postman-Token:[e9fa290c-8757-4eef-bcc9-5a9fb39a2d0b] User-Agent:[PostmanRuntime/7.28.1] X-Forwarded-For:[199.36.223.53] X-Forwarded-Proto:[https]] Body:{} GetBody:<nil> ContentLength:0 TransferEncoding:[] Close:false Host:(company):2087 Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr:(company ip):14286 RequestURI:/auth TLS:0xc0003ea0b0 Cancel:<nil> Response:<nil> ctx:0xc0005881c0}
auth           | I0804 14:02:39.066004       1 server.go:456] Auth request: {:@(company ip):14286 []}
auth           | I0804 14:02:39.066029       1 server.go:295] Authn static  -> true, map[], <nil>
auth           | I0804 14:02:39.077271       1 server.go:407] New token for {:@(company ip):14286 []} map[]: {"iss":"company-token-issuer","sub":"","aud":"","exp":1628086659,"nbf":1628085749,"iat":1628085759,"jti":"1006871144220648292","access":[]}
auth           | I0804 14:02:39.077324       1 server.go:492] {"access_token":"(some token)"}

Am I doing something wrong? Thanks

liangyuanpeng commented 3 years ago

Could you try cesanta/docker_auth:1.8 again? Thanks. @luke-pefi

lgprobert commented 2 years ago

I hit the same issue. The version I used is 1.9.0