LDAP Integration?

Hi there,

I have a basic Orthanc server up and running on a Red Hat box through the latest docker image, and am loving it. Next step is to integrate with our enterprise LDAP (for read-only authentication validation, only), and it seems that there are many possible approaches to accomplish such LDAP integration.

Here’s what I have explored or considered so far:

  1. “Implement a Lua callback to filter incoming REST requests. This is the most simple solution, and would notably allow you to implement read-only access or, more generally, access control lists.”.

    I have explored some of the Lua samples and integrated a quick test HelloWorld.lua that implements the “OnStoredInstance()” callback. This looks good for some triggered functionality, but are such Lua Server-Side scripts a reasonable place to setup an initial LDAP authentication? Server-side scripting with Lua — Orthanc Book documentation (“Server-side scripting with Lua - Filtering incoming REST requests”) indicates that the use of IncomingHttpRequestFilter() could be applicable, and I wonder if SetHttpCredentials(username, password) might likewise tie in somehow.

  2. "Develop a C/C++ plugin that uses the OrthancPluginRegisterIncomingHttpRequestFilter(). This solution is potentially useful if you wish to integrate with an LDAP server."

    This currently seems to be the most likely candidate, but I am unsure of whether or not I can do so using the pre-built docker image. I see some starting clues on C/C++ plugins at Creating new plugins — Orthanc Book documentation (“Creating new plugins”) and the example Implementing a WADO Server using Orthanc - CodeProject (“Implementing a WADO Server using Orthanc”), but nothing regarding the deprecated OrthancPluginRegisterIncomingHttpRequestFilter() or its newer OrthancPluginRegisterIncomingHttpRequestFilter2() except for a wee bit of description on the API page itself at http://sdk.orthanc-server.com/ .

    Although I would love to simply connect a plugin into the latest pre-built docker image for such a plugin, I would be more than willing to build the image locally if that is what is required to make this happen. A bit more guidance there might be very nice, though, or at least some assurance that this is indeed the recommended path before investing much more time here.

  3. Use Orthanc as a reverse proxy (e.g. behind nginx, Apache, or Microsoft IIS), and use the authentication mechanisms of the main Web server.

    I have looked a little bit at How can I run Orthanc behind nginx? — Orthanc Book documentation ("How can I run Orthanc behind nginx?") and have attempted the nginx configuration snippet, but even that “location /orthanc/” snippet does not yet seem to work for me (results in a 502 Bad Gateway at first pass).

    I am using the latest docker image for nginx along with jwilder/docker-gen:0.3.4, and am unsure if these can be configured directly for LDAP. Clues point to trying to build NGINX Plus with an nginx-ldap-auth.conf (as per Using NGINX Plus and NGINX to Authenticate Users with LDAP), but I am hoping to stick with a pre-built nginx image, if at all possible since this is already a relatively finicky part of our infrastructure, and I am hesitate to increase its complexity too much more.

  4. Create a new Web user interface on the top of the REST API of Orthanc, using your favorite framework (Meteor, AngularJS, Ember.js, Node.js…)

    Not sure I want to go down this path if unnecessary since I really do like the existing Orthanc web user interface, and don’t want to merely reinvent its already quite usable wheel.

Sorry, don’t really intend to open up that thread, except to highlight one very relevant line where Sébastien recommends:

So you need LDAP? Just implement it with a PHP/Django/nginx wrapper around Orthanc. Bottom line.

I like the sounds of this (!!!), and it seems like a great approach. Given my lack of success so far with nginx alone (above), I tried a few tweaks to a Django app that is on the same server, but am not yet sure of the details to approach this. My test Django app is already integrated with LDAP for authentication, and is sitting under http://myhost/app. I would love to configure an endpoint such as http://myhost/app/orthanc which is safely within the net of the Django app.

If I understand correctly, though, I can only configure the port for Orthanc, and not its endpoint, is that right? And that would require that I do get the nginx proxy_pass setup properly, yes?

I also wonder, though, if a savvy user could still gain access directly to the redirected URL (e.g., http://localhost:8042) to bypass any Django-based authentication under its configured SITEAUTH_ALLOW_URLS.

Any other thoughts on the use of Django or PHP as such a wrapper? I really do like the idea of such an approach, if I can make it happen.

mentions that "Orthanc does not support LDAP authentication out-of-the-box, but a plugin can be developed using the
“OrthancPluginRegisterIncomingHttpRequestFilter()” primitive: Creating new plugins — Orthanc Book documentation "

also recommends that “Orthanc 1.0.1 will also allow the possibility to filter incoming HTTP requests with a C/C++ plugin (check out the new “OrthancPluginRegisterIncomingHttpRequestFilter()” function in the mainline code).

With all of the above shared, I suppose that a relatively simple wrapper approach that allows me to continue using the pre-built Orthanc docker image would be ideal. If not, I do expect that my next best option is implementing a plugin to utilize OrthancPluginRegisterIncomingHttpRequestFilter() but do, again, hope for a little more guidance before starting into that path.

Might any of you be able to kindly provide any further details, examples, or guidance on any techniques for any such LDAP integration?

Thank you very much,
Remo

I’m no expert in the use of the proxy, but for what it’s worth, we’ve set up our Orthancs here behind an Apache proxy. I then am able to use our university’s single sign on service, which happens to have a drop in module for Apache.

We run everything through https, including the Orthancs. That requires generating self-signed certificates on the Orthanc side. Our Orthancs are run within docker containers and appear as separate subnets behind the proxy. To get apache to play nice with the SSL proxypass and self-signed certs, I found I had to tweak a few parameters in the proxy conf file that pointed to each Orthanc. These included settings like SSLProxyCheckPeer* and adding a pointer to the Orthanc certificate (SSLProxyCACertificateFile) so that Apache could see it.

Regarding users making an end-run around the authentication service by logging in from the host machine, I manage this with a series of iptable firewall rules on the host machine. I use the “owner” module to restrict access to the 8042 port to the apache uid only. The iptable rule looks like:

iptables -A OUTPUT -o MYNIC -p tcp -m tcp --dport 8042 -m owner --uid-owner 48 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 8042 -j DROP

It took a while to figure out the settings that worked and I’m not even sure these are ideal. It was helpful initially to ramp up the Apache logging so I could see why my initial attempts at the proxy were failing.

Good luck,
John.

Hi Remo,

There are many proposals in your post and many of them might work.

I would really recommend delegating the LDAP authentication to another app (I would clearly avoid the lua script; Writing a C++ plugin would be great and would benefit everybody but that might be the most demanding solution).

The Apache/Nginx reverse-proxying are probably the ones that requires less coding from your part but I’m not familiar with LDAP nginx plugins (and not familiar at all with Apache). If you had troubles running orthanc behind nginx, I can point you to this sample: https://bitbucket.org/osimis/orthanc-setup-samples/src/cdb8ba00ff51/docker/tls-with-nginx/?at=master that should be working out of the box and that could be a good starting point for you (note that it’s actually much more complex than what you need since it involves 3 orthanc and client certificate authentication → just look at nginx and orthanc-a).

I read that you already have a django app that implements LDAP authentication → that’s also a very good starting point. You would “just” need to implement a reverse proxy to orthanc in your django app.
This means that your django app should catch all /orthanc/… urls, check if the user has the right to access orthanc and if yes, forward the call to orthanc (most likely on http://localhost:8042), get the response from orthanc and forward it as a response in your django app. Note that it seems that there exists some reverse-proxy django modules out of the box.

So good luck for this and please, keep us informed once you have a working solution.