Mercurial > hg > orthanc-python
view Resources/Samples/SampleHttpAuthentication.py @ 334:ff7d48d8d51a default tip
added Resources/Samples/SampleHttpAuthentication.py
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 21 Aug 2026 16:32:47 +0200 |
| parents | |
| children |
line wrap: on
line source
# SPDX-FileCopyrightText: 2020-2023 Osimis S.A., 2024-2026 Orthanc Team SRL, 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain # SPDX-License-Identifier: AGPL-3.0-or-later ## ## Python plugin for Orthanc ## Copyright (C) 2020-2023 Osimis S.A., Belgium ## Copyright (C) 2024-2026 Orthanc Team SRL, Belgium ## Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium ## ## This program is free software: you can redistribute it and/or ## modify it under the terms of the GNU Affero General Public License ## as published by the Free Software Foundation, either version 3 of ## the License, or (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## Affero General Public License for more details. ## ## You should have received a copy of the GNU Affero General Public License ## along with this program. If not, see <http://www.gnu.org/licenses/>. ## # # Sample Python plugin illustrating how to implement basic # cookie-based user authentication. # # This sample uses plain session cookies. A more realistic # implementation would use JWT-based authentication. # import json import orthanc import urllib.parse CREDENTIALS = { 'admin' : 'admin', } ROOT = '/authentication-sample' COOKIE_LOGGED_USER = 'logged_user' COOKIE_BAD_CREDENTIALS = 'bad_credentials' HTML_PAGE_LOGIN = ''' <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Orthanc sample authentication</title> </head> <body> <h1>Orthanc sample authentication</h1> %s <form action="do-login" method="POST"> <p>Username: <input type="text" name="username"></input></p> <p>Password: <input type="password" name="password"></input></p> <button type="submit">Log in</button> </form> </body> </html>''' HTML_PAGE_LOGGED = ''' <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Orthanc sample authentication</title> </head> <body> <h1>Orthanc sample authentication</h1> <p>You are logged as: <b>%s</b></p> <form action="do-logout" method="POST"> <button type="submit">Log out</button> </form> <p><a href=".." target="_blank"><button>Open Orthanc Explorer</button></a></p> </body> </html> ''' def SetSessionCookie(output, cookie, value): output.SetHttpHeader('Set-Cookie', '%s=%s; HttpOnly; SameSite=Lax; Secure; Path=/' % (cookie, value)) def ClearSessionCookie(output, cookie): output.SetHttpHeader('Set-Cookie', '%s=; HttpOnly; SameSite=Lax; Secure; Path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' % cookie) def Login(output, uri, **request): authentication = json.loads(request['authentication_payload']) if 'username' in authentication: output.AnswerBuffer(HTML_PAGE_LOGGED % authentication['username'], 'text/html') else: if authentication.get('bad_credentials') == 'true': bad_credentials = '<p><b>Bad credentials were provided</b></p>' ClearSessionCookie(output, COOKIE_BAD_CREDENTIALS) # Only warn once about bad credentials else: bad_credentials = '' output.AnswerBuffer(HTML_PAGE_LOGIN % bad_credentials, 'text/html') def DoLogin(output, uri, **request): body = dict(urllib.parse.parse_qsl(request['body'].decode('utf-8'))) username = body.get('username') password = body.get('password') if (username != None and password != None and CREDENTIALS.get(username) == password): # Correct credentials SetSessionCookie(output, COOKIE_LOGGED_USER, username) ClearSessionCookie(output, COOKIE_BAD_CREDENTIALS) else: # Wrong credentials ClearSessionCookie(output, COOKIE_LOGGED_USER) SetSessionCookie(output, COOKIE_BAD_CREDENTIALS, 'true') output.SetHttpHeader('Location', 'index.html') output.SendHttpStatusCode(302) # Redirection def DoLogout(output, uri, **request): ClearSessionCookie(output, COOKIE_LOGGED_USER) ClearSessionCookie(output, COOKIE_BAD_CREDENTIALS) output.SetHttpHeader('Location', 'index.html') output.SendHttpStatusCode(302) # Redirection def DoAuthentication(uri, ip, headers, get): authentication_payload = { # It is a good practice to inform other plugins (such as # orthanc-wsi) about the plugin that generated the # authentication payload 'source' : 'orthanc-python-sample-authentication', } is_logged = False for (key, value) in headers.items(): if key == 'cookie': for value in value.split(';'): cookie = value.split('=') cookieName = cookie[0].strip() cookieValue = cookie[1].strip() if cookieName == COOKIE_LOGGED_USER: authentication_payload['username'] = cookieValue is_logged = True elif cookieName == COOKIE_BAD_CREDENTIALS: authentication_payload['bad_credentials'] = cookieValue authentication_payload = json.dumps(authentication_payload).encode('utf-8') # From JSON string to bytes if uri.startswith(ROOT): # Always grant access to the routes related to login/logout return (orthanc.HttpAuthenticationStatus.GRANTED, authentication_payload, None) elif is_logged: # You could return orthanc.HttpAuthenticationStatus.FORBIDDEN # if the logged user tries to access a resource for which the # credentials are not sufficient return (orthanc.HttpAuthenticationStatus.GRANTED, authentication_payload, None) else: # Request authentication is the user is not logged in yet return (orthanc.HttpAuthenticationStatus.REDIRECT, authentication_payload, '%s/index.html' % ROOT) orthanc.RegisterHttpAuthenticationCallback(DoAuthentication) orthanc.RegisterRestCallback('%s/do-login' % ROOT, DoLogin) orthanc.RegisterRestCallback('%s/do-logout' % ROOT, DoLogout) orthanc.RegisterRestCallback('%s/index.html' % ROOT, Login)
