docker registry 认证流程

参考: https://docs.docker.com/registry/spec/auth/token/

最近在使用harbor的过程中,定位了一个docker认证相关的问题,期间因为对docker registry的认证流程不熟悉,花了不少时间,这里把整个流程梳理一下。

大部分的流程在上面给出的官方文档中已经说的比较清楚,首先看这个图: auth

  1. Docker client发起一个pull请求

  2. 如果Registry配置了需要认证,会返回401 Unauthorized和接下来如何认证的信息

  3. Docker使用registry提供的认证方法获取token

  4. 认证服务返回一个token

  5. Docker将token以bearer token的方式放在header中再次发起第一步的请求

  6. Registry对token进行验证通过后开始pull流程

其中第二步registry的返回类似于这样:

1
2
3
4
5
6
7
8
9
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:samalba/my-app:pull,push"
Date: Thu, 10 Sep 2015 19:32:31 GMT
Content-Length: 235
Strict-Transport-Security: max-age=31536000

{"errors":[{"code":"UNAUTHORIZED","message":"access to the requested resource is not authorized","detail":[{"Type":"repository","Name":"samalba/my-app","Action":"pull"},{"Type":"repository","Name":"samalba/my-app","Action":"push"}]}]}

在上面这个http response中,关于接下来如何认证的信息并不是放在body中,而是在Www-Authenticate这个header里。其中realm就是认证服务的地址,service代表registry服务的提供方,scope则是本次请求涉及的权限相关信息,例子中就是对samalba/my-app这个镜像的pull和push操作请求权限认证。

第三步请求token时要带上刚才拿到的service和scope参数:

1
https://auth.docker.io/token?service=registry.docker.io&scope=repository:samalba/my-app:pull,push

看到这里其实有一点疑问,认证服务本身又是如何认证的呢?总不能谁都能发起这个请求拿到token吧,那就相当于不认证了。通过在harbor中打印日志的方式,发现docker在请求token时带着一个basicauth的header:

1
Authorization: Basic xxxx

Xxxx是一个base64编码后的字符串,编码前的格式是username:password,而这组用户名密码,其实是docker login的时候使用的。之后的流程不再赘述,完整的流程如下:

  1. Docker client发起一个login请求,使用basicauth的方式携带用户名密码

  2. Registry返回401 Unauthorized和接下来如何认证的信息

  3. Docker使用registry提供的认证方法获取token

  4. 认证服务返回一个token

  5. docker login成功,docker将认证信息存储到本地文件

  6. Docker client发起一个pull请求,根据registry的地址找到存储在本地的用户名密码并以basicauth的方式携带

  7. Registry返回401 Unauthorized和接下来如何认证的信息

  8. Docker使用registry提供的认证方法获取token

  9. 认证服务返回一个token

  10. Docker将token以bearer token的方式放在header中再次发起第6步的请求

  11. Registry对token进行验证通过后开始pull流程