Authorization plugin seems to forbide post /instances API

Hi there,

We may found a bug in the authorization plugin, we try to have a custom authorization only for the dicom web API, this last API will be the only one exposed to the internet while we want to keep other orthanc API “opened” for all user (as will be accessible only through a LAN)

we tried this configuration :

  "Authorization": {
    "WebServiceRootUrl": "http://orthanc-auth-service:8000/",
    "WebServiceUsername": "share-user",
    "WebServicePassword": "change-me",
    //    "CheckedLevel": "studies",
    "UncheckedLevels": [
      "system"
    ],
    "UncheckedFolders": [
      "/"
    ]
  },

Seems to work to access orthanc APIs but for some strange reason the POST call on /instances are always returned 403 and we don’t even see Orthanc trying to validate these request to the authorization backend.

Is there a specific protection for the instance creation endpoint ?

Best regards,

Salim

Hi Salim,

Actually, I think the documentation for UncheckedFolders was not clear. I have updated the text now:

UncheckedFolders specifies a list of root paths for which the authentication plugin is not triggered when receiving a GET request. This is actually mainly used to grant access to static resources e.g. HTML and JS resources from plugins like Orthanc Explorer 2.

So, in your system, all resources are accessible in GET which means /patients?expand as well which is maybe not something you expect since it provides patient information to everyone - I assume you are blocking the traffic by another mean.

With your configuration file, I can see that the POST /instances is being checked at “user permission level”:

I0126 15:05:37.349101           HTTP-0 HttpServer.cpp:1262] (http) GET /instances
I0126 15:05:45.123997           HTTP-1 HttpServer.cpp:1262] (http) POST /instances
I0126 15:05:45.124133           HTTP-1 PluginsManager.cpp:161] (plugins) Testing whether anonymous user has any of the required permissions 'all|upload'
I0126 15:05:45.124216           HTTP-1 PluginsManager.cpp:161] (plugins) Testing whether anonymous user has any of the required permissions 'all|upload' -> not granted

But it is not being checked if I configure the resource level validation only with this configuration:

"Authorization": {
    //"WebServiceRootUrl": "http://orthanc-auth-service:8000/",
    "WebServiceTokenValidationUrl" : "http://orthanc-auth-service:8000/tokens/validate",

It is not being checked because, the resource level validation are supposed to grant READ ONLY accesses e.g. when sharing a link to share a single study.

In your use case, as I understand it, you are trying to provide read only resource level authorization to the DICOMWeb interface (that is connected to the WAN) and user level authorization for LAN users and grant them full read/write access ?

For this scenario, I would strongly recommand running 2 Orthanc instances connected to the same DB and configure one for the WAN and one for the LAN. This makes things a lot easier to configure/understand/security check.

Hope this helps.

Alain.

Note: I will really try to improve the authorization plugin documentation …

1 Like

FYI, I have just completely reworked the documentation of this plugin.

I came across this post because I am having similar issue.

  1. I had orthanc using an Authorization token in the header which was added in my Nginx Proxy Manager (NPM). This was allowing me to POST /instances and GET /ohif/viewer?StudyInstanceUIDs=${id}. However, this was not protecting from someone uploading or accessing the files directly.
  2. I added the advance authorization plugin (Advanced authorization plugin — Orthanc Book documentation) and setup my configuration like so
"Authorization" : {
  "Enabled": false,
  "WebServiceTokenValidationUrl" : "http://my-auth-server/api/auth/verify-access",
  "TokenHttpHeaders" : [ "token" ],
  "TokenGetArguments" : [ "token" ],
  "StandardConfigurations": [
    "stone-webviewer",
    "dicom-web",
    "ohif"
  ],
  "CheckedLevel" : "studies",
}

I then added “token=xxxx” to the url query. This worked to protect access to the documents. However, now uploading documents (POST /instance) no longer works. I receive a 403 HTTP status response.
3. I read through documentation and forum and found this recommended change to the orthanc configuration.

"Authorization" : {
  "Enabled": false,
  "WebServiceTokenValidationUrl" : "http://my-auth-server/api/auth/verify-access",
  "TokenHttpHeaders" : [ "token" ],
  "TokenGetArguments" : [ "token" ],
  "StandardConfigurations": [
    "stone-webviewer",
    "dicom-web",
    "ohif"
  ],
  "CheckedLevel" : "studies",
  "Permissions" : [
    ["post", "^/instances$", "all|upload"]
  ],  
  "DicomCheckModality": false,
  "AllowFind": true,
  "AllowStore": true
}

However, this has not resolved my issue. I am still receiving 403 response. I don’t see my authentication server receiving any request when attempting to upload documents, but I do see it hit when I attempt to access the documents for viewing.

My scenario is:

  • orthanc and ohif running in separate docker containers
  • my frontend and backend running in different docker containers.
  • my front end uses an iframe for the ohif viewer (which required lots of advanced configuration under NPM)
  • my backend handles uploading files to orthanc.

If I revert back to using “AuthenticatonEnbled: true” then upload and viewing works, but the access is not secured because any attempts to go through the proxy which attaches the required Auth header. If I use the Authorization plugin, viewing works, but the upload never calls authorization server, instead I immediately get a 403 response. I also attempted uploading in Postman which provided the same results. It worked when not using authorization plugin and fails with 403 when authorization plugin is configured.

I am using jodogne/orthanc-plugins:latest (sha256:27be55e619be1c40f5c59ca74c1ec9f3edf173e4ca574ff101ee8cf8999a0d91)

Any guidance would be appreciated.

Hi,

When you open the OHIF viewer with token=…, you are using a resource token that grant access to a single resource.

When you want to POST to /instances, you can not use a resource token, you can only do it with a user token which means you need to implement the user-profile routes for the permission system to work and allow access to POST /instances.

Useful samples:

HTH,

Alain

Hi Alian,

Thank you for pointing me in the right direction.

Alain,

I have gotten a little further, but the POST instances/ is still responding with 403.

  1. I changed my docker image from jodogne/orthanc-plugins to orthancteam/orthanc:25.2.0 which is used the in the examples you provided.
  2. I updated my orthanc.json to
  "AuthenticationEnabled": false,
  "RegisteredUsers": {
    "user1": "user1",
    "user2": "user2",
    "admin": "admin"
  },
  "Authorization" : {
    "WebServiceUserProfileUrl" : "http://my-auth-server:3000/api/auth/user/get-profile",
    "WebServiceTokenValidationUrl" : "http://my-auth-server:3000/api/auth/verify-access",
    "TokenHttpHeaders" : [ "token" ],
    "TokenGetArguments" : [ "token" ],
    "StandardConfigurations": [
      "orthanc-explorer-2",
      "stone-webviewer",
      "dicom-web",
      "ohif"
    ],
    "CheckedLevel" : "studies"
  },
  "OrthancExplorer2": {
    "Tokens": {
      // experimental, set it to false when using basic-auth together with the auth-plugin (https://discourse.orthanc-server.org/t/user-based-access-control-with-label-based-resource-access/5454)
      "RequiredForLinks": false
    }
  },

NOTE: the sample at orthanc-setup-samples/docker/access-control-user-profiles/docker-compose.yml at master · orthanc-server/orthanc-setup-samples · GitHub shows “AuthenticationEnabled”: true. But if I set this in my config I see errors on starting container and it keeps rebooting
3. I attempted to implement all the auth paths, not just ‘user/get-profile’ and ‘tokens/validate’, but that did no seem to help.

If I call GET instances/ I can see my user/get-profile route being hit. But If I call POST instance. I just see this message in the orthanc logs, it does not attempt to hit my ‘user/get-profile’ route.

HTTP-1 PluginsManager.cpp:162] (plugins) Testing whether anonymous user has any of the required permissions ‘all|upload’

Here is the JSON I am currently returning from my user/get-profile route.

    const response = {
      name: 'test',
      'authorized-labels': ['*'],
      permissions: ['all', 'view', 'upload'],
      validity: 60
    }

It seems as if I am missing some configuration that is needed so the POST uses my auth webhooks.

Also, now in my app, when I attempt to view a file http://viewer.test.localhost/ohif/viewer?StudyInstanceUIDs=1.3.12.2.1107.5.4.3.123456789012345.19950922.121803.6&token=xxxx

I get the following response, which I assume is because I changed container images. The jodogne/orthanc-plugins seems to have OHIF plugin configured but does not have the good logging I see in orthancteam/orthanc:25.2.0 (but the orthancteamc does not come configured with OHIF plugin). I was using the same orthanc.json file for both images.

{
	"HttpError" : "Not Found",
	"HttpStatus" : 404,
	"Message" : "Unknown resource",
	"Method" : "GET",
	"OrthancError" : "Unknown resource",
	"OrthancStatus" : 17,
	"Uri" : "/ohif/viewer"
}

CONCLUSION

I just found my issue. The POST /instances did not like the token as a param. I added the token to my headers and it worked.

Testing with Postman, now I will move it into the application code and see if I can get all scenarios to work.

With all the information I have provided, can you suggest if I am using Orthanc and OHIF the best way possible. For example, the OHIF viewer took a good amount of reverse proxy custom configration to handle all the network traffic.

Any suggestion or recommendations are appreciated.