|
| 1 | +# Token Authentication with Keycloak |
| 2 | + |
| 3 | +In this example, we'll see how to configure your keycloak server and use token authentication with your registry. This will use the [docker registry v2 token authentication protocol](https://docs.docker.com/registry/spec/auth/token/). |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +In this image, we will replace the docker client/daemon by the Docker Registry UI. Here are the steps: |
| 8 | + |
| 9 | +1. Attempt to get a resource (catalog, image info, image delete) with the registry. |
| 10 | +2. If the registry requires authorization it will return a `401 Unauthorized` HTTP response with information on how to authenticate. |
| 11 | +3. The **docker registry ui** makes a request to **keycloak** for a Bearer token. |
| 12 | + 1. Your browser will use the [Basic Access Authentication Protocol](https://en.wikipedia.org/wiki/Basic_access_authentication#Protocol). But keycloak does not support this protocol... That's why we need a nginx proxy on top of keycloak. |
| 13 | + 2. Your proxy will receive a request on `/auth/realms/{realm name}/protocol/docker-v2/auth` without `Authentication` header. It will return a `401 Unauthorized` HTTP response with `WWW-Authenticate` header. |
| 14 | + 3. Your browser will ask you your credentials. |
| 15 | + 4. The proxy will pass the credentials to keycloak. |
| 16 | +4. Keycloak returns an opaque Bearer token representing the client’s authorized access. |
| 17 | +5. The **docker registry ui** retries the original request with the Bearer token embedded in the request’s Authorization header. |
| 18 | +6. The Registry authorizes the client by validating the Bearer token and the claim set embedded within it and begins the session as usual. |
| 19 | + |
| 20 | +:warning: If you are configuring from scratch your own keycloak server, remove files in `data` folder first with certificates in `conf/registry/localhost.*` |
| 21 | + |
| 22 | +## Configure your nginx/proxy server |
| 23 | + |
| 24 | +I will highlight required configuration for Basic Access Authentication Protocol. Replace the `{realm name}` by the name of your realm. In my example the realm is master, but you should create your own realm for your users. |
| 25 | + |
| 26 | +```nginx |
| 27 | + resolver 127.0.0.11 valid=30s; |
| 28 | + set $keycloak "http://keycloak:8080"; |
| 29 | +
|
| 30 | + # Location to get keycloak token |
| 31 | + location /auth/realms/{realm name}/protocol/docker-v2/auth { |
| 32 | + proxy_set_header X-Forwarded-Proto $scheme; |
| 33 | + proxy_set_header Host $host; |
| 34 | + proxy_set_header X-Forwarded-Host $host; |
| 35 | + # By default, keycloak returns 400 instead of 401, we need to change that |
| 36 | + if ($http_authorization = "") { |
| 37 | + add_header WWW-Authenticate 'Basic realm="Keycloak login"' always; |
| 38 | + return 401; |
| 39 | + } |
| 40 | + proxy_pass $keycloak; |
| 41 | + } |
| 42 | +``` |
| 43 | + |
| 44 | +Start your nginx server. It will be available on http://localhost/ in my example. |
| 45 | + |
| 46 | +```sh |
| 47 | +docker-compose up -d proxy |
| 48 | +``` |
| 49 | + |
| 50 | +## Configure your keycloak server |
| 51 | + |
| 52 | +I will highlight required configuration for docker protocol. You will need to add this option to your keycloak command line: |
| 53 | + |
| 54 | +``` |
| 55 | +-Dkeycloak.profile.feature.docker=enabled |
| 56 | +``` |
| 57 | + |
| 58 | +Then the defalt user can be configured via environment variables |
| 59 | +```yml |
| 60 | +services: |
| 61 | + keycloak: |
| 62 | + image: jboss/keycloak |
| 63 | + environment: |
| 64 | + KEYCLOAK_USER: admin |
| 65 | + KEYCLOAK_PASSWORD: password |
| 66 | + user: root |
| 67 | + networks: |
| 68 | + - registry-ui-net |
| 69 | + command: -Dkeycloak.profile.feature.docker=enabled -b 0.0.0.0 |
| 70 | +``` |
| 71 | +
|
| 72 | +Now you can start your keycloak server, it will be available on http://localhost/auth in my example. |
| 73 | +
|
| 74 | +
|
| 75 | +```sh |
| 76 | +docker-compose up -d keycloak |
| 77 | +``` |
| 78 | + |
| 79 | +Now you need to configure your docker client with these steps: |
| 80 | + |
| 81 | +Go to the keycloak home page: http://localhost/auth and click on `Administration Console`. |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | +Sign in with your login and password (in my example it's `admin` and `password`). |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +Go to `Clients` in the left side menu. |
| 90 | + |
| 91 | + |
| 92 | + |
| 93 | +Create a new client. |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | +Enter a name for `Client ID`, choose `docker-v2` as the `Client Protocol`, and click `Save`. |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +Navigate to `Installation` tab, choose `Docker Compose YAML` as `Format Option` and click `Download` |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | +When you extract the archive, the resulting directory should look like this. |
| 106 | + |
| 107 | +``` |
| 108 | +keycloak-docker-compose-yaml |
| 109 | +├── certs |
| 110 | +│ ├── localhost.crt |
| 111 | +│ ├── localhost.key |
| 112 | +│ └── localhost_trust_chain.pem |
| 113 | +├── data |
| 114 | +├── docker-compose.yaml |
| 115 | +└── README.md |
| 116 | +``` |
| 117 | + |
| 118 | +Copy all the files from `certs` folder to `conf/registry` (this will replace files generated for this example). |
| 119 | + |
| 120 | +## Configure your registry server |
| 121 | + |
| 122 | +The last step is the configuration of your registry server. The config file is located in `conf/registry/config.yml`. The import part of the configuration is `auth.token` where you need to set `realm`, `service`, `issuer` and the `rootcertbundle` from the previous archive. |
| 123 | + |
| 124 | +```yml |
| 125 | +auth: |
| 126 | + token: |
| 127 | + realm: http://localhost/auth/realms/{realm name}/protocol/docker-v2/auth |
| 128 | + service: docker-registry |
| 129 | + issuer: http://localhost/auth/realms/{realm name} |
| 130 | + rootcertbundle: /etc/docker/registry/localhost_trust_chain.pem |
| 131 | +``` |
| 132 | +
|
| 133 | +Now you can start your docker registry with your docker registry ui. |
| 134 | +
|
| 135 | +```sh |
| 136 | +docker-compose up -d registry ui |
| 137 | +``` |
0 commit comments