Intro
I was doing so well.
Thanks to the help @alainmazy gave me I managed to get everything working, but I don’t know what I did that broke everything. I was getting ready to put everything into production, changing the secrets, deleting the test databases and creating new databases for the orthanc index and the Keycloak realm.
But now when I try to access Orthanc I can authenticate but I can’t see any functionality in OE2 and in the logs I get:
orthanc-auth-service-1 | INFO: 172.18.0.4:54764 - "GET /settings/roles HTTP/1.1" 401 Unauthorized
orthanc-auth-service-1 | INFO: 172.18.0.4:54776 - "POST /user/get-profile HTTP/1.1" 401 Unauthorized
I don’t know what I might have misconfigured by accident.
Configuration
services:
# Container 1: Proxy Reverso com SSL
nginx:
image: orthancteam/orthanc-nginx:24.7.2
depends_on: [ orthanc, orthanc-dicom-tls, orthanc-dicom, orthanc-auth-service, keycloak, ohif ]
restart: unless-stopped
ports: [ "443:443" ]
volumes:
- ./tls/crt.pem:/etc/nginx/tls/crt.pem:ro
- ./tls/key.pem:/etc/nginx/tls/key.pem:ro
environment:
ENABLE_ORTHANC: "true"
ENABLE_KEYCLOAK: "true"
ENABLE_ORTHANC_TOKEN_SERVICE: "false"
ENABLE_HTTPS: "true"
ENABLE_OHIF: "true"
# Container 2: Static OHIF
ohif:
image: orthancteam/ohif-v3:24.7.2
restart: unless-stopped
# Container 3: ORTHANC PACS (DICOMweb, GUI)
orthanc:
image: orthancteam/orthanc:24.8.3
restart: unless-stopped
volumes:
- ./tmp/orthancDicomWeb-logs:/logs
- ./orthancDicomWeb.json:/etc/orthanc/orthanc.json:ro
environment:
# Console Logs
VERBOSE_ENABLED: "true"
VERBOSE_STARTUP: "true"
# Logs
LOGDIR: "/logs"
ORTHANC__DE_IDENTIFY_LOGS: "false"
# Container 4: ORTHANC PACS (DISME)
orthanc-dicom-tls:
image: orthancteam/orthanc:24.8.3
restart: unless-stopped
ports:
- "2762:4242"
volumes:
- ./tmp/orthancDicomTLS-logs:/logs
- ./orthancDicomTLS.json:/etc/orthanc/orthanc.json:ro
- ./tls:/tls:ro
environment:
# Console Logs
VERBOSE_ENABLED: "true"
VERBOSE_STARTUP: "true"
# Logs
LOGDIR: "/logs"
ORTHANC__DE_IDENTIFY_LOGS: "false"
# Container 5: ORTHANC PACS (DISME)
orthanc-dicom:
image: orthancteam/orthanc:24.8.3
restart: unless-stopped
ports:
- "104:4242"
volumes:
- ./tmp/orthancDicom-logs:/logs
- ./orthancDicom.json:/etc/orthanc/orthanc.json:ro
environment:
# Console Logs
VERBOSE_ENABLED: "true"
VERBOSE_STARTUP: "true"
# Logs
LOGDIR: "/logs"
ORTHANC__DE_IDENTIFY_LOGS: "false"
# Container 6: Auth Interface Orthanc < > KeyCloak
orthanc-auth-service:
image: orthancteam/orthanc-auth-service:24.7.2
volumes:
- ./permissions.json:/orthanc_auth_service/permissions.json
depends_on: [ keycloak ]
restart: unless-stopped
env_file:
- "./.auth.env"
# Container 7: Auth
keycloak:
image: orthancteam/orthanc-keycloak:24.7.2
restart: unless-stopped
env_file:
- "./.keycloak.env"
The idea of this configuration is that I have NGINX to observe HTTPS communications (Layer 7: Application Layer) and redirect to:
- OHIF,
- Orthanc Web Server (DICOMweb) and Remote Access,
- Orthanc-auth-service,
- KeyCloak
The other Orthancs have Remote Access turned off and are just gateways to DICOM operating in TCP (Layer 4: Network Layer). These are usually the ones known as DISME or SPU, I don’t know if there is a difference or if each one calls it what they want. One Orthanc with active TLS to protect communication and another without for devices that are not capable of secure communication. What I don’t know is if it is really necessary to have this unsecured server.
orthanc.json (Config Files)
orthancDicomWeb.json
{
"Name": "SOME AWESOME NAME",
"ConcurrentJobs": 0,
"JobsEngineThreadsCount": {
"ResourceModification": 1
},
"HttpServerEnabled": true,
"HttpPort": 8042,
"HttpDescribeErrors": true,
"HttpCompressionEnabled": false,
"WebDavEnabled": false,
"DicomServerEnabled": false,
"SslEnabled": false,
"RemoteAccessAllowed": true,
"OrthancExplorer2": {
"IsDefaultUI": true,
"UiOptions": {
"EnableShares": true,
"DefaultShareDuration": 0,
"ShareDurations": [
0,
7,
15,
30,
90,
365
],
"EnableOpenInOhifViewer3": true,
"OhifViewer3PublicRoot": "https://my.already.changed.url/ohif/"
},
"Tokens": {
"InstantLinksValidity": 3600,
"ShareType": "ohif-viewer-publication"
},
"Keycloak": {
"Enable": true,
"Url": "https://my.already.changed.url/keycloak/",
"Realm": "orthanc",
"ClientId": "orthanc"
}
},
"AuthenticationEnabled": false,
"Authorization": {
"WebServiceRootUrl": "http://orthanc-auth-service:8000/",
"WebServiceUsername": "SOME SHARE USER",
"WebServicePassword": "SOME SHERE PASSWORD",
"StandardConfigurations": [
"orthanc-explorer-2",
"ohif"
],
"CheckedLevel": "studies"
},
"DicomWeb": {
"Enable": true,
"PublicRoot": "/orthanc/dicom-web/"
},
"PostgreSQL": {
"EnableIndex": true,
"Host": "AWS RDS HOST",
"Port": 5432,
"Database": "orthanc",
"Username": "postgres",
"Password": "SOME AWESOME PASSWORD",
"EnableSsl": true
},
"AwsS3Storage": {
"BucketName": "SOME AWESOME BUCKET NAME",
"Region": "us-east-1",
"AccessKey": "SOME ACCESS KEY",
"SecretKey": "SOME SECRET KEY",
"StorageStructure": "flat",
"UseTransferManager": true
}
}
Why did I remove the HttpHeaders Token? I don’t intend to use API-KEY, but I saw that it is possible to generate tokens through Keycloak to pass as a query string in the URL to gain access to the resources. If the correct token is not passed, the resource will not be loaded.
I also removed RegisteredUsers since all of this will be in Keycloak.
But what would a resource be for me?
My use case:
I need Orthanc to be the gateway only, with a single user who is able to log in in case of an audit, an admin.
The OHIF will always be accessed using the studyInstaceUID to find which DICOM to load and using the Keycloak token.
So a resource is a DICOM loaded by OHIF for doctors to view.
I will not use the open button by OHIF within OE2 or share a link, much less create a user for each doctor.
So my env for Orthanc-auth-service and Keycloak looked like this:
ENV
.auth.env
SECRET_KEY="SOME AWESOME SECRET KEY (64 caracters: Uppercase, lowercase, numbers, special characters)"
ENABLE_KEYCLOAK="true"
# ENABLE_KEYCLOAK_API_KEYS="true"
# KEYCLOAK_CLIENT_SECRET="SECRET OBTAINED INSIDE KEYCLOAK"
PUBLIC_ORTHANC_ROOT="https://my.already.changed.url/orthanc/"
PUBLIC_LANDING_ROOT="https://my.already.changed.url/orthanc/ui/app/token-landing.html"
PUBLIC_OHIF_ROOT="http://my.already.changed.url/ohif/"
USERS={ "SOME SHARE USER":"SOME SHERE PASSWORD" }
.keyclock.env
KEYCLOAK_ADMIN="ADMIN USER WHO HAS NOTHING TO DO WITH Orthanc-Auth-Service"
KEYCLOAK_ADMIN_PASSWORD="SOME AWESOME PASSWORD (64 caracters: Uppercase, lowercase, numbers, special characters)"
# KC_FEATURES="fips[:v1]"
# KC_FIPS_MODE="strict"
KC_DB="postgres"
KC_DB_URL="AWS RDS HOST"
KC_DB_USERNAME="postgres"
KC_DB_PASSWORD="SOME AWESOME PASSWORD"
KC_HOSTNAME_URL="https://my.already.changed.url/keycloak"
KC_HOSTNAME_ADMIN_URL="https://my.already.changed.url/keycloak"
# QUARKUS_TRANSACTION_MANAGER_ENABLE_RECOVERY=true
What did I do wrong? I think my eyes are so glazed that I’m not seeing the mistake I made.
I am following the information in the following links:
Docker Hub orthanc-auth-service
Github Minimal Setup Docker Compose
Orthanc orthanc-auth-service Repo
Docker Config guide for Keycloak
Thank you for your time.