Orthanc + Auth Service+ Keycloak user logging

Hello Everyone,

Thank you for the great work that you do.

I am running Orthanc along with auth service, my users are defined in Keycloak.

I would like Orthanc logs to display Keycloak usernames for the actions that they’re undertaking for security purposes. Is this possible with current versions? what needs to be done to achieve this?

I also have another, more advanced but related question:

I am working on a workflow whereby doctors will send a study to an orthanc peer, which will trigger AI analysis. I would like to notify doctors by email/SMS with results once the analysis is complete. The issue is that my data on the requesting doctor is in Keycloak, including their email and phone numbers. Is it at all possible to get this data into Orthanc? as far as I understand the JWT contains the following data:

“preferred_username”: “doctor”,
“given_name”: “Name”,
“family_name”: “Surname”

If I modify auth service to include the additional data that I may need, would I be able to utilize this from Orthanc through Lua/Python scripts?

Kind Regards,

Yomarbuzz

For accessing user details in Keycloak from an Orthanc script, you could use the Keycloak REST API: Keycloak Admin REST API. Or possibly query it’s database tables depending on where you created the user accounts.

Todd Jensen, PhD
Jensen Informatics LLC

Hi Todd,

Thanks for your response. My issue is that it seems that Orthanc doesn’t know which doctor is performing an action (no username / given name in logs). If I were to identify which user sent study x to orthanc peer y then I would follow your suggestion and fetch additional details like email and phone over Keycloak API.

Hi,

You may try to implement your own version of IncomingHttpFilter in python. You should get the HTTP headers and url which should be enough for you to do what you need.

However, since you are already using the authorization plugin that is also implementing this filter, I can not guarantee that it will work. Please give it a try and report your findings.

Best regards,

Alain.

Hi Alain,

Thanks for your response, it worked, but it requires the use of pyjwt library, which I’ve had to manually install into the container.

Python plugin would greatly benefit from a feature that allows us to specify requirements.txt in config that would be installed with pip when entrypoint is ran. Having to include all packages you need in CI or manually installing into running containers complicates python script development for Orthanc. Please let me know if I’m missing something and there is an easier way to do this.

More on topic, following script works for capturing and logging keycloak name, username, email and roles on URI accesses. In my experience it doesn’t conflict with Auth plugin, thanks for your suggestion.

import orthanc
import pprint
import jwt

def Filter(uri, **request):
    headers = request.get('headers', {})
    
    # Capture the value of the "token" header
    token = headers.get('token')
    
    # Proceed only if there is a token
    if token:
        try:
            # Decode the JWT without verification (for demonstration purposes)
            decoded_jwt = jwt.decode(token, options={"verify_signature": False})
            
            # Extract the required information
            roles = decoded_jwt.get('realm_access', {}).get('roles', [])
            name = decoded_jwt.get('name', 'Unknown')
            preferred_username = decoded_jwt.get('preferred_username', 'Unknown')
            email = decoded_jwt.get('email', 'Unknown')
            
            # Print the extracted information along with the URI being accessed
            print(f'User: {name} (Username: {preferred_username}, Email: {email}) is accessing URI: {uri}')
            print(f'Roles: {roles}')
        except Exception as e:
            print(f"Failed to decode JWT: {e}")
            return True 
    
    # If there is no token or after processing the token, grant access
    return True

orthanc.RegisterIncomingHttpRequestFilter(Filter)

Great that it worked and thanks for sharing your script !

No, you’re not missing something. Feel free to create an issue here for better tracking of that feature request.

Best,

Alain