Metadata-Version: 2.1 Name: django-simple-sso Version: 1.3.0 Summary: Simple SSO for Django Home-page: http://github.com/aldryn/django-simple-sso Author: Divio AG Author-email: info@divio.com License: BSD-3-Clause Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Framework :: Django Classifier: Framework :: Django :: 2.2 Classifier: Framework :: Django :: 3.0 Classifier: Framework :: Django :: 3.1 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Libraries License-File: LICENSE Requires-Dist: Django >=2.2 Requires-Dist: itsdangerous <1.0.0 Requires-Dist: requests ================= django-simple-sso ================= |pypi| |build| |coverage| Documentation ============= See ``REQUIREMENTS`` in the `setup.py `_ file for additional dependencies: |python| |django| Django Simple SSO Specification (DRAFT) ======================================= Terminology *********** Server ------ The server is a Django website that holds all the user information and authenticates users. Client ------ The client is a Django website that provides login via SSO using the **Server**. It does not hold any user information. Key --- A unique key identifying a **Client**. This key can be made public. Secret ------ A secret key shared between the **Server** and a single **Client**. This secret should never be shared with anyone other than the **Server** and **Client** and must not be transferred unencrypted. Workflow ******** * User wants to log into a **Client** by clicking a "Login" button. The initially requested URL can be passed using the ``next`` GET parameter. * The **Client**'s Python code does a HTTP request to the **Server** to request a authentication token, this is called the **Request Token Request**. * The **Server** returns a **Request Token**. * The **Client** redirects the User to a view on the **Server** using the **Request Token**, this is the **Authorization Request**. * If the user is not logged in the the **Server**, they are prompted to log in. * The user is redirected to the **Client** including the **Request Token** and a **Auth Token**, this is the ``Authentication Request``. * The **Client**'s Python code does a HTTP request to the **Server** to verify the **Auth Token**, this is called the **Auth Token Verification Request**. * If the **Auth Token** is valid, the **Server** returns a serialized Django User object. * The **Client** logs the user in using the Django User received from the **Server**. Requests ******** General ------- All requests have a ``signature`` and ``key`` parameter, see **Security**. Request Token Request --------------------- * Client: Python * Target: **Server** * Method: GET * Extra Parameters: None * Responses: * ``200``: Everything went fine, the body of the response is a url encoded query string containing with the ``request_token`` key holding the **Request Token** as well as the ``signature``. * ``400``: Bad request (missing GET parameters) * ``403``: Forbidden (invalid signature) Authorization Request --------------------- * Client: Browser (User) * Target: **Server** * Method: GET * Extra Parameters: * ``request_token`` * Responses: * ``200``: Everything okay, prompt user to log in or continue. * ``400``: Bad request (missing GET parameter). * ``403``: Forbidden (invalid **Request Token**). Authentication Request ---------------------- * Client: Browser (User) * Target: **Client** * Method: GET * Extra Parameters: * ``request_token``: The **Request Token** returned by the **Request Token Request**. * ``auth_token``: The **Auth Token** generated by the **Authorization Request**. * Responses: * ``200``: Everything went fine, the user is now logged in. * ``400``: Bad request (missing GET parameters). * ``403``: Forbidden (invalid **Request Token**). Auth Token Verification Request ------------------------------- * Client: Python * Target: **Server** * Method: GET * Extra Parameters: * ``auth_token``: The **Auth Token** obtained by the **Authentication Request**. * Responses: * ``200``: Everything went fine, the body of the response is a url encoded query string containing the ``user`` key which is the JSON serialized representation of the Django user to create as well as the ``signature``. Security ******** Every request is signed using HMAC-SHA256. The signature is in the ``signature`` parameter. The signature message is the urlencoded, alphabetically ordered query string. The signature key is the **Secret** of the **Client**. To verify the signature the ``key`` paramater holding the **key** of the **Client** is also sent with every request from the **Client** to the **Server**. Example ------- GET Request with the GET parameters ``key=bundle123`` and the private key ``secret key``: ``fbf6396d0fc40d563e2be3c861f7eb5a1b821b76c2ac943d40a7a63b288619a9`` The User object *************** The User object returned by a successful **Auth Token Verification Request** does not contain all the information about the Django User, in particular, it does not contain the password. The user object contains must contain at least the following data: * ``username``: The unique username of this user. * ``email``: The email of this user. * ``first_name``: The first name of this user, this field is required, but may be empty. * ``last_name``: The last name of this user, this field is required, but may be empty. * ``is_staff``: Can this user access the Django admin on the **Client**? * ``is_superuser``: Does this user have superuser access to the **Client**? * ``is_active``: Is the user active? Implementation ************** On the server ------------- * Add ``simple_sso.sso_server`` to ``INSTALLED_APPS``. * Create an instance (potentially of a subclass) of ``simple_sso.sso_server.server.Server`` and include the return value of the ``get_urls`` method on that instance into your url patterns. On the client ------------- * Create a new instance of ``simple_sso.sso_server.models.Consumer`` on the **Server**. * Add the ``SIMPLE_SSO_SECRET`` and ``SIMPLE_SSO_KEY`` settings as provided by the **Server**'s ``simple_sso.sso_server.models.Client`` model. * Add the ``SIMPLE_SSO_SERVER`` setting which is the absolute URL pointing to the root where the ``simple_sso.sso_server.urls`` where include on the **Server**. * Add the ``simple_sso.sso_client.urls`` patterns somewhere on the client. Running Tests ************* You can run tests by executing:: virtualenv env source env/bin/activate pip install -r tests/requirements.txt python setup.py test .. |pypi| image:: https://badge.fury.io/py/django-simple.sso.svg :target: http://badge.fury.io/py/django-simple.sso .. |build| image:: https://travis-ci.org/divio/django-simple.sso.svg?branch=master :target: https://travis-ci.org/divio/django-simple.sso .. |coverage| image:: https://codecov.io/gh/divio/django-simple.sso/branch/master/graph/badge.svg :target: https://codecov.io/gh/divio/django-simple.sso .. |python| image:: https://img.shields.io/badge/python-3.5+-blue.svg :target: https://pypi.org/project/django-simple.sso/ .. |django| image:: https://img.shields.io/badge/django-2.2,%203.0,%203.1-blue.svg :target: https://www.djangoproject.com/