Keyrock doesn't recognize super-admin user - docker

I'm making a project for a course in uni. I'm running a keyrock container in docker and I use a .http file to make direct request for X-Auth-Token with the default super-admin user. The request:
###get X-Auth-Token directly in keyrock
GET http://localhost:3005/v1/auth/tokens
Content-Type: application/json
{"email":"admin#test.com","password":"1234"}
From what I understand in the documentation this super-user is initialized by the keyrock service by default and the request is the same as keyrock documentation, except if I made some error. This is what it returns:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0
Content-Type: application/json; charset=utf-8
Content-Length: 83
ETag: W/"53-HM/hhsSfxoQsxV7mUMAoJqvJdJ0"
Date: Sat, 14 Jan 2023 11:02:23 GMT
Connection: close
{
"error": {
"message": "Invalid email or password",
"code": 401,
"title": "Unauthorized"
}
}
I will also show the docker-compose file for clarity:
version: "3.8"
networks:
idm_network:
driver: bridge
#project images
services:
# projectapp:
# build: ./projectapp
# networks:
# - idm_network
# depends_on:
# - keyrock
# ports:
# - "8080:8080"
# expose:
# - 8080
mysql:
build: ./mysql
command:
- "--default-authentication-plugin=mysql_native_password"
networks:
- idm_network
volumes:
- mysqlVolume:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=idm
- MYSQL_ROOT_HOST=%
- MYSQL_USER=root
- MYSQL_DATABASE=idm
keyrock:
image: fiware/idm:7.6.0
networks:
- idm_network
depends_on:
- mysql
ports:
- "3005:3000"
- "443:443"
environment:
- IDM_DB_HOST=mysql
- IDM_HOST=http://localhost:3005
- IDM_PORT=3005
- IDM_DB_USER=root
- IDM_ADMIN_USER=admin
- IDM_ADMIN_EMAIL=admin#test.com
- IDM_ADMIN_PASS=1234
.
.
.
#project volumes
volumes:
mysqlVolume:
mongoOrionVolume:
mongoDataVolume:
Don't all these environment variables in keyrock mean that is the default admin user's credentials?
Thank you for your time.

Ok, so apparently the admin user is not added by default you have to create it. In the step-by-step guide: https://github.com/FIWARE/tutorials.Identity-Management/tree/NGSI-v2 in the mysql-data there is a .sql backup file that should be added in the initialization process.
Inside this file in line 710 or so you can add as many users as you want and there you can add your default super admin user with any credentials you want. I know it worked, because in the container CLI I can now see the idm database, the tables and the user I created in the 'user' table.
Unfortunately, my request still doesn't work, I'm not sure why, but this should work for most people I assume.

Related

Unable to obtain ACME certificate for domains - trying to setup HTTPS in virtual localhost on docker

I am trying to setup a certificate for a locally running react app on a virtual host local.example.com. This has to just work locally on docker setup. After going through some articles, I came up with this docker-compose.yml:
version: "3"
services:
mongo:
image: mongo
restart: always
ports:
- "27017:27017"
volumes:
- mongodbdata:/data/db
networks:
- proxy
mongo-express:
image: mongo-express
restart: always
ports:
- "8081:8081"
networks:
- proxy
react:
build:
context: ./client
dockerfile: ./Dockerfile
ports:
- "3001:3001"
stdin_open: true
volumes:
- ./client:/client
- /client/node_modules
labels:
# this enables traefik for your service
- "traefik.enable=true"
# this defines the url, traefik will get the ssl certificate for
- "traefik.http.routers.myapplication.rule=Host(`local.example.com`)"
# this tells traefik to use https to access the website
- "traefik.http.routers.myapplication.entrypoints=websecure"
# this tells traefik to use the certresolver, that we defined above for resolving tls (in our case letsencrypt)
- "traefik.http.routers.myapplication.tls.certresolver=myresolver"
# this let's us forward the port we set above. Change this to the port you expose in your application (3000, 4000, ...) or remove the line, if your application already exposes port 80/443
- "traefik.http.services.myapplication.loadbalancer.server.port=3000"
depends_on:
- "server"
networks:
- proxy
server:
build:
context: ./server
dockerfile: ./Dockerfile
ports:
- "5001:5001"
volumes:
- traefik.toml:/traefik.toml
- acme.json:/acme.json
- ./server:/server
- /server/node_modules
labels:
# this enables traefik for your service
- "traefik.enable=true"
# this defines the url, traefik will get the ssl certificate for
- "traefik.http.routers.myapplication.rule=Host(`local.example.com`)"
# this tells traefik to use https to access the website
- "traefik.http.routers.myapplication.entrypoints=websecure"
# this tells traefik to use the certresolver, that we defined above for resolving tls (in our case letsencrypt)
- "traefik.http.routers.myapplication.tls.certresolver=myresolver"
# this let's us forward the port we set above. Change this to the port you expose in your application (3000, 4000, ...) or remove the line, if your application already exposes port 80/443
- "traefik.http.services.myapplication.loadbalancer.server.port=5001"
depends_on:
- "mongo"
networks:
- proxy
whoami:
image: "containous/whoami"
container_name: "myapplication"
restart: unless-stopped
ports:
- "4000:4000"
networks:
- proxy
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
# this can be uncommented to get more information, in case something doesn't work
- "--log.level=DEBUG"
# set this to true to get access to the traefik web interface unter http://YOURIP:8080
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # uncomment this line to only test ssl generation first (to make sure you don't run into letsencrypt limits)
- "--certificatesresolvers.myresolver.acme.email=kamlekar.venkatesh#gmail.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080" # this is used for the web interface, that let's you check and monitor traefik and your configuration. It's very nice for debugging your config - only available if "api.insecure" above is set to true
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- proxy
# The following is only necessary if you want to enforce https!
# if you don't need that, you can just remove the labels here
labels:
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
networks:
proxy:
external: true
volumes:
mongodbdata:
traefik.toml:
acme.json:
On doing docker-compose up, I am seeing the following error in traefik service. Also, though the react app service is running in docker but I hit https://local.example.com:3001, is unreachable
time="2022-01-23T08:30:52Z" level=error msg="Unable to obtain ACME certificate for domains "local.example.com": unable to generate a certificate for the domains [local.example.com]: error: one or more domains had a problem:\n[local.example.com] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: NXDOMAIN looking up A for local.example.com - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for local.example.com - check that a DNS record exists for this domain, url: \n" providerName=myresolver.acme routerName=myapplication#docker rule="Host(local.example.com)"
Here are the research notes which I tried till now (These notes for only my personal understanding so could be not in detail)
You can start from this fiddle: https://github.com/kamlekar/react-docker-ssl-virtualhost
You need to use TLS for your local setup. The host you need a certificate for is local.example.com. There is no way to obtain a certificate from Letsencrypt for this name, because you're not controlling the example.com domain. One of the ways Letsencrypt creates a certificate is a challenge - you prove that you own the domain by creating a TXT DNS record. If you own a domain you can do that, but your case is different, because you only need this for local development.
However, you can just use openssl to generate a self signed certificate for whichever domain name you want. This is a good reference on how to do this. You can use the local.example.com domain name for the generated certificate. If you're successful, you'll end up with the certificate and it's private key. Note where you save those files, as you'll need them. Keep in mind that the certificate is self-signed, so your browser will give you a warning, unless you add this certificate to the trust store of your operating system.
The next step in your case is to make Traefik use those self signed certificates when serving content from your application. I think this answer has a good example of that.
After having this, you'll only need to edit your hosts file and redirect your localhost:8080 (the port on which your Traefik serves your application) to local.example.com.
Also, Traefik is not the only solution for your case. You can also achieve the same using Nginx, for example. Choose which one satisfies your use case. My suggestion would be to use the one that's easiest to configure, because it's for local development. Here's the first result I got when searching for a nginx docker-compose self-signed certificate.
UPDATE
Here's a quick example of what I'm describing above.
First generate the certificate:
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -sha256 -days 1000 -subj '/CN=local.example.com'
You'll end up with two files in your current directory (key.pem and cert.pem). Now create the nginx.conf:
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 443 ssl;
server_name local.example.com;
ssl_certificate cert.pem;
ssl_certificate_key key.pem;
ssl_session_timeout 5m;
location / {
proxy_pass http://myapp:8080;
proxy_set_header Host $host;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}
}
}
And now the docker-compose.yaml file:
version: "3"
services:
nginx:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./cert.pem:/etc/nginx/cert.pem
- ./key.pem:/etc/nginx/key.pem
ports:
- "443:443"
networks:
- local-dev-01
myapp:
image: your-react-app-image
command: "command-that-starts-your-app"
networks:
- local-dev-01
networks:
local-dev-01:
Docker creates a network called local-dev-01 for you, which allows both services to be able to resolve each other by their name. That's why we have myapp:8080 in the nginx.conf. We also mount the configuration and the generated certificate and key for local.example.com.
The final step is to edit your hosts file and add the following line:
127.0.0.1 local.example.com
After that, you should have no trouble reaching your application on https://local.example.com on your machine. Keep in mind that your browser will keep warning you that the certificate is self-signed, so you should add it as an exception.

How to properly call another docker container via axios?

So I'm currently building a docker setup with a REST API and a separate frontend. My backend consists of Symfony 5.2.6 as REST API and my frontend is a simple Vue application.
When I try to call my API from the vue application via localhost or 127.0.0.1, I get a "Connection refused" error. When I try to call the API via the external IP of my server, I run into CORS issues. This is my first setup like this, so I'm kind of at a loss.
This is my docker setup:
version: "3.8"
services:
# VUE-JS Instance
client:
build: client
restart: always
logging:
driver: none
volumes:
- ./client:/app
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
- NODE_ENV=development
ports:
- 8080:8080
# SERVER
php:
build: php-fpm
restart: always
ports:
- "9002:9000"
volumes:
- ./server:/var/www/:cached
- ./logs/symfony:/var/www/var/logs:cached
# WEBSERVER
nginx:
build: nginx
restart: always
ports:
- "80:80"
volumes_from:
- php
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./logs/nginx/:/var/log/nginx:cached
So what is the correct way to establish the connection between those two containers?
The client app runs on port 8080 but nginx on 80 is a different URL and it should be a CORS error.
To avoid it, in the PHP app, you have to add response header:
Access-Control-Allow-Origin: http://localhost:8080 or
Access-Control-Allow-Origin: *.
Another solution is to configure all in one domain on this same port.

Containers with docker-compose have different behavior depending on machine where they are executed

Good day,
I'm trying to make the below docker-compose working on my machine but I have issues with some 404 errors when trying to access url of container A from container B.
A priori the only thing which wasn't in the source control was a modification in the host file where I had to add the following rows.
127.0.0.1 idsrv4admin.traefik.me
127.0.0.1 idsrv4adminApi.traefik.me
127.0.0.1 login.traefik.me
I got all resources from source control and on my friend's machine it's working fine.
Maybe I have a different configuration on my machine but I can't find out what it is.
If I try to access "http://login.traefik.me/.well-known/openid-configuration" directly from my browser I can access it:
{"issuer":"http://login.traefik.me","authorization_endpoint":"http://login.traefik.me/connect/authorize","token_endpoint":"http://login.traefik.me/connect/token","userinfo_endpoint":"http://login.traefik.me/connect/userinfo","end_session_endpoint":"http://login.traefik.me/connect/endsession","check_session_iframe":"http://login.traefik.me/connect/checksession","revocation_endpoint":"http://login.traefik.me/connect/revocation","introspection_endpoint":"http://login.traefik.me/connect/introspect","device_authorization_endpoint":"http://login.traefik.me/connect/deviceauthorization","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"backchannel_logout_supported":true,"backchannel_logout_session_supported":true,"scopes_supported":["roles","openid","profile","email","address","identity_admin_api","offline_access"],"claims_supported":["role","sub","updated_at","locale","zoneinfo","birthdate","gender","website","picture","preferred_username","nickname","middle_name","given_name","family_name","name","profile","email","email_verified","address"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password","urn:ietf:params:oauth:grant-type:device_code"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"subject_types_supported":["public"],"code_challenge_methods_supported":["plain","S256"],"request_parameter_supported":true}
If I connect from the container admin and I try a curl on the same url I have a 404 with the following error message:
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x560c38473f50)
* Connected to login.traefik.me (127.0.0.1) port 80 (#0)
> GET /.well-known/openid-configuration HTTP/1.1
> Host: login.traefik.me
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Date: Mon, 23 Nov 2020 08:34:58 GMT
< Content-Length: 0
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SameOrigin
< Referrer-Policy: no-referrer
< Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/ https://fonts.gstatic.com/;font-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/
<
* Connection #0 to host login.traefik.me left intact
Below is the docker-compose:
version: "3.4"
services:
traefik:
image: "traefik:latest"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik.address=:9090"
ports:
- "80:80"
- "443:443"
- "9090:9090"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- proxy
admin:
image: ${DOCKER_REGISTRY-}admin:latest
build:
context: .
dockerfile: src/IdentityServer/Admin/Dockerfile
container_name: is4-admin
hostname: idsrv4admin.traefik.me
expose:
- '80'
labels:
- "traefik.enable=true"
- "traefik.http.routers.identityserver4Admin.rule=Host(`idsrv4admin.traefik.me`)"
- "traefik.http.routers.identityserver4Admin.entrypoints=web"
environment:
- VIRTUAL_HOST=idsrv4admin.traefik.me
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:80
- DOTNET_USE_POLLING_FILE_WATCHER=1
- "AdminConfiguration__IdentityAdminRedirectUri=http://idsrv4admin.traefik.me/signin-oidc"
- "AdminConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
- "AdminConfiguration__RequireHttpsMetadata=false"
depends_on:
- sts.identity
- admin.api
networks:
- proxy
admin.api:
image: ${DOCKER_REGISTRY-}admin-api:latest
build:
context: .
dockerfile: src/IdentityServer/Admin.Api/Dockerfile
container_name: is4-admin-api
hostname: idsrv4adminApi.traefik.me
labels:
- "traefik.enable=true"
- "traefik.http.routers.identityserver4AdminApi.rule=Host(`idsrv4adminApi.traefik.me`)"
- "traefik.http.routers.identityserver4AdminApi.entrypoints=web"
environment:
- VIRTUAL_HOST=idsrv4adminApi.traefik.me
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:80
- DOTNET_USE_POLLING_FILE_WATCHER=1
- "AdminApiConfiguration__RequireHttpsMetadata=false"
- "AdminApiConfiguration__ApiBaseUrl=http://idsrv4adminApi.traefik.me"
- "AdminApiConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
depends_on:
- sts.identity
networks:
- proxy
sts.identity:
image: ${DOCKER_REGISTRY-}sts-identity:latest
build:
context: .
dockerfile: src/IdentityServer/STS.Identity/Dockerfile
container_name: is4-sts-identity
hostname: login.traefik.me
labels:
- "traefik.enable=true"
- "traefik.http.routers.identityserver4STS.rule=Host(`login.traefik.me`)"
- "traefik.http.routers.identityserver4STS.entrypoints=web"
environment:
- VIRTUAL_HOST=login.traefik.me
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:80
- DOTNET_USE_POLLING_FILE_WATCHER=1
- "AdminConfiguration__IdentityAdminBaseUrl=http://idsrv4admin.traefik.me"
networks:
- proxy
networks:
proxy:
driver: bridge
Anybody has an idea ?
Thank in advance
You are trying to connect to 127.0.0.1 Connected to login.traefik.me (127.0.0.1) port 80 (#0) which will send you to 127.0.0.1 inside your admin container and not on your machine
To make it work you need to map login.traefik.me to your local address (192.168.x.x)
Also, it would be better if you call that endpoint with the service name, since all the containers are in the same network you can replace this environement variable
- "AdminApiConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
With
- "AdminApiConfiguration__IdentityServerBaseUrl=http://sts.identity:80"
You are using hostnames provided by the traefik.me service which (similar to xip.io) provides a wildcard DNS service by resolving domains to IPs according to the subdomain pattern.
For example, a dns query to myapp.1.2.3.4.traefik.me will resolve to the IP address encoded in the subdomain 1.2.3.4. If you don't specify an IP address in the subdomain (and not using the hexadecimal notation, too), this service automatically resolves to 127.0.0.1 which works in most cases for host-to-container setups.
Running on your host machine, using this IP address (the localhost) is pointing to your host machine. As you have traefik exposed using docker compose, this works as the request from your local machine to your local machine is mapped to the container (due to the ports mapping you defined for traefik).
This is not the case when running inside the container itself. See the log output of your curl command:
* Connected to login.traefik.me (127.0.0.1) port 80 (#0)
Running the exact same request from inside one of the containers will also resolve to the 127.0.0.1 IP, but inside a container this IP address is no longer your host machine address, but the loopback adapter of the container network interface. So basically you are running into a pretty common issue about the meaning of 127.0.0.1 when using containers as already answered several times here:
PHP app cannot connect to docker mysql container at 127.0.0.1
docker-compose + django + redis - Error 111 connecting to 127.0.0.1:6379. Connection refused
Rails app using docker-compose wont connect to the mysql container
So if you need to have one single dns name that works from the host and from the container, you need to switch to something like login.192.168.1.123.traefik.me assuming 192.168.1.123 is your host IP address. But as you notice this needs adaption for each single developer and even when you change the network/wifi you are connected to.
So, I guess there is no go-to solution for this using such a wildcard dns service if you want to use the exact same domain name for public access and inter-container calls. In a production scenario, the hostname would resolve to a globally valid public IP address that also works when accessed from inside the container as it would go a full round trip through traefik, but this is not really a good option for such a development setup.
In this scenario, you would really need to specify different domains depending on if you are issuing a redirect (using the globally valid domain) or if you are using a direct call from one container to another. Those are reachable using the docker-compose internal service names, e.g. like http://sts.identity or - less preferred - the container name (http://is4-sts-identity). Can you specify that those urls are used instead of the public ones by configuring the environment variable AdminApiConfiguration__IdentityServerBaseUrl accordingly?

Traefik 2.2 + Docker + Websocket (ws) not working

I'ved managed to get it Traefik working for http containers but when I switched to websocket, had no luck. Traefik is pretty easy. Let me share it's docker-compose file:
version: "3.3"
services:
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
# - "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entryPoints.ws.address=:81" #I ADDED THIS
- "--accesslog"
ports:
- "80:80"
- "81:81" #I ADDED THIS
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
To make it easier, I added and comment like #I ADDED THIS so you can see the changes I've made to make WS work.
Now on the actual project docker-compose I've added this labels:
version: '2.1'
services:
test:
restart: unless-stopped
hostname: test
build:
context: .
dockerfile: ./Dockerfile
expose:
- 81
labels:
- "traefik.enable=true"
- "traefik.http.routers.test.rule=Host(`test.com`)"
- "traefik.http.routers.test.entrypoints=ws"
- "traefik.http.services.test.loadBalancer.sticky.cookie=true"
And I'm trying to connect using Nodejs:
var ws = new WebSocket('ws://test.com:81')
Dont know what else to try.
Thank you in advanced.
EDIT Saw in traefik log:
time="2020-08-23T16:07:28Z" level=debug msg="vulcand/oxy/roundrobin/rr: completed ServeHttp on request" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Connection\":[\"Upgrade\"],\"Sec-Websocket-Extensions\":[\"permessage-deflate; client_max_window_bits\"],\"Sec-Websocket-Key\":[\"jaXhUWe2lvrgxF0tOn3nWA==\"],\"Sec-Websocket-Version\":[\"13\"],\"Upgrade\":[\"websocket\"],\"X-Forwarded-Host\":[\"test.com:81\"],\"X-Forwarded-Port\":[\"81\"],\"X-Forwarded-Proto\":[\"ws\"],\"X-Forwarded-Server\":[\"58077bdceffd\"],\"X-Real-Ip\":[\"192.168.99.1\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"test.com:81\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.99.1:56705\",\"RequestURI\":\"/\",\"TLS\":null}"
192.168.99.1 - - [23/Aug/2020:16:07:07 +0000] "GET / HTTP/1.1" 499 21 "-" "-" 56 "test#docker" "http://172.19.0.2:81" 21082ms
Looks right, but still no communication between client/server.
I think you need to add service port to your test container:
- "traefik.http.services.test.loadbalancer.server.port=81"
edit:
for traefik to be able to discover your service, it needs to be on same network. so best solution seems to define external network for both services or use the one defined with your websocket service

Accessing Keycloak-Service inside Docker by its Network Alias

Scenario
I have secured webservice (JakartaEE + Microprofile + JWT) running in open liberty. As issuer of the jwt token I use keycloak. For testing and development i want to run both services in docker. Therefore I wrote a docker-compose file. As test client I use JUnit with microprofile-client. This is running outside of docker.
Problem
I can retrieve the JWT-Token via localhost at the host - e.g.:
POST /auth/realms/DC/protocol/openid-connect/token HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
realm=DC&grant_type=password&client_id=dc&username=dc_editor&password=******
The problem is, that from the perspective of the webservice localhost isn't the keycloak server. The JWT-Token-Validation against the issuer fails.
Goal
I want to access the keycloak server from the host with its docker-internal network alias - e.g. dcAuthServer. The JWT-Token would be validated correctly.
Code
The docker-compose file looks like this:
version: "3.8"
services:
dcWebservice:
environment:
- DC_AUTH_SERVER_HOST=dcAuthServer
- DC_AUTH_SERVER_PORT=8080
- DC_AUTH_SERVER_REALM=DC
image: dc_webservice:latest
ports:
- "9080:9080"
networks:
- dcNetwork
dcAuthServer:
image: dc_keycloak:latest
ports:
- "8080:8080"
networks:
dcNetwork:
aliases:
- dcAuthServer
healthcheck:
test: "curl --fail http://localhost:8080/auth/realms/DC || false"
networks:
dcNetwork:
The environment DC_AUTH* are used in the mpJwt-configuration in server.xml of the open liberty server:
<mpJwt id="dcMPJWT" audiences="dc" issuer="http://${DC_AUTH_SERVER_HOST}:${DC_AUTH_SERVER_PORT}/auth/realms/${DC_AUTH_SERVER_REALM}"
jwksUri="http://${DC_AUTH_SERVER_HOST}:${DC_AUTH_SERVER_PORT}/auth/realms/${DC_AUTH_SERVER_REALM}/protocol/openid-connect/certs"/>
The issuer is where I have to put a trusted issuer for the JWT-Token.
I hope I did not forget important information - just ask!
Thanks in advance
Robert

Resources