Metadata-Version: 2.1
Name: django-pyoidc
Version: 0.0.13
Summary: Authenticate your users using OpenID Connect (OIDC)
Author-email: "Régis Leroy (Makina Corpus)" <django_pyoidc@makina-corpus.net>, "Paul Florence (Makina Corpus)" <django_pyoidc@makina-corpus.net>
Project-URL: repository, https://gitlab.makina-corpus.net/pfl/django-pyoidc
Keywords: openid,oidc,django,sso,single-sign-on,openid-connect
Classifier: Topic :: Utilities
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Topic :: Security
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: oic==1.7.0
Requires-Dist: django>=3.2
Requires-Dist: jsonpickle
Requires-Dist: jwt
Provides-Extra: test
Requires-Dist: alabaster==0.7.13; extra == "test"
Requires-Dist: asgiref==3.8.1; extra == "test"
Requires-Dist: attrs==23.2.0; extra == "test"
Requires-Dist: babel==2.15.0; extra == "test"
Requires-Dist: certifi==2024.2.2; extra == "test"
Requires-Dist: cfgv==3.4.0; extra == "test"
Requires-Dist: charset-normalizer==3.3.2; extra == "test"
Requires-Dist: colorama==0.4.6; extra == "test"
Requires-Dist: distlib==0.3.8; extra == "test"
Requires-Dist: django==4.2.13; extra == "test"
Requires-Dist: django-cors-headers==4.3.1; extra == "test"
Requires-Dist: djangorestframework==3.15.1; extra == "test"
Requires-Dist: docutils==0.19; extra == "test"
Requires-Dist: exceptiongroup==1.2.1; extra == "test"
Requires-Dist: filelock==3.14.0; extra == "test"
Requires-Dist: h11==0.14.0; extra == "test"
Requires-Dist: identify==2.5.36; extra == "test"
Requires-Dist: idna==3.7; extra == "test"
Requires-Dist: imagesize==1.4.1; extra == "test"
Requires-Dist: isort==5.13.2; extra == "test"
Requires-Dist: jinja2==3.1.4; extra == "test"
Requires-Dist: livereload==2.6.3; extra == "test"
Requires-Dist: markupsafe==2.1.5; extra == "test"
Requires-Dist: nodeenv==1.8.0; extra == "test"
Requires-Dist: outcome==1.3.0.post0; extra == "test"
Requires-Dist: packaging==24.0; extra == "test"
Requires-Dist: platformdirs==4.2.2; extra == "test"
Requires-Dist: pre-commit==3.5.0; extra == "test"
Requires-Dist: psycopg2==2.9.9; extra == "test"
Requires-Dist: pygments==2.18.0; extra == "test"
Requires-Dist: pysocks==1.7.1; extra == "test"
Requires-Dist: python-decouple==3.8; extra == "test"
Requires-Dist: pyyaml==6.0.1; extra == "test"
Requires-Dist: requests==2.32.1; extra == "test"
Requires-Dist: selenium==4.21.0; extra == "test"
Requires-Dist: six==1.16.0; extra == "test"
Requires-Dist: sniffio==1.3.1; extra == "test"
Requires-Dist: snowballstemmer==2.2.0; extra == "test"
Requires-Dist: sortedcontainers==2.4.0; extra == "test"
Requires-Dist: sphinx==6.2.1; extra == "test"
Requires-Dist: sphinx-autobuild==2021.3.14; extra == "test"
Requires-Dist: sphinx-rtd-theme==2.0.0; extra == "test"
Requires-Dist: sphinxcontrib-applehelp==1.0.4; extra == "test"
Requires-Dist: sphinxcontrib-devhelp==1.0.2; extra == "test"
Requires-Dist: sphinxcontrib-htmlhelp==2.0.1; extra == "test"
Requires-Dist: sphinxcontrib-jquery==4.1; extra == "test"
Requires-Dist: sphinxcontrib-jsmath==1.0.1; extra == "test"
Requires-Dist: sphinxcontrib-qthelp==1.0.3; extra == "test"
Requires-Dist: sphinxcontrib-serializinghtml==1.1.5; extra == "test"
Requires-Dist: sqlparse==0.5.0; extra == "test"
Requires-Dist: tornado==6.4; extra == "test"
Requires-Dist: trio==0.25.1; extra == "test"
Requires-Dist: trio-websocket==0.11.1; extra == "test"
Requires-Dist: typing-extensions==4.11.0; extra == "test"
Requires-Dist: urllib3[socks]==2.2.1; extra == "test"
Requires-Dist: virtualenv==20.26.2; extra == "test"
Requires-Dist: wsproto==1.2.0; extra == "test"

# Makina Django OIDC


<p align="center">
<a href="https://django-pyoidc.readthedocs.io">
        <img src="https://readthedocs.org/projects/django-pyoidc/badge/?version=main" />
</a>
</p>

This library allow *Single Sign On* (SSO) integration into Django through the [Open ID Connect (OIDC)]() protocol.

It can be used to setup a Single Sign On using an identity provider (Keycloak, etc.) or to login using Google, Twitter, etc.

**Warning** : this library has not been audited. However, we are based on [pyoidc](https://github.com/CZ-NIC/pyoidc/) which we believe is a sane OIDC implementation.

## Features

- Easy configuration through premade [`Provider`](https://django-pyoidc.readthedocs.io/en/latest/user.html#providers) classes.
- Multiple provider support
- Easy integration with the [Django permission system](https://django-pyoidc.readthedocs.io/en/latest/how-to.html#use-the-django-permission-system-with-oidc)
- Highly customizable design that should suit most needs
- Back-channel Logout
- Sane and secure defaults settings

## Roadmap

- `Bearer` authentication support for `django-rest-framework` integration
- Frontchannel logout

## Acknowledgement

This library is built on the work of many others. First all, thanks to all the maintainers of [pyoidc](https://github.com/CZ-NIC/pyoidc/) as they did all the spec implementation. This library is mostly about glue between Django and *pyoidc*.

We were also heavily inspired by :

* [`mozilla-django-oidc`](https://github.com/mozilla/mozilla-django-oidc) for it's login redirection URI management
* [`django-auth-oidc`](https://gitlab.com/aiakos/django-auth-oidc) for it's hook system

If you want to understand why we decided to implement our own library, this is documented [here](https://django-pyoidc.readthedocs.io/en/latest/explanation.html#other-oidc-libraries).

## Documentation

The documentation is graciously hosted at [readthedocs](https://django-pyoidc.readthedocs.io).

## Installation

First, install the python package :

```bash
pip install makina-django-doic
```

Then add the library app to your django applications, after `django.contrib.sessions` and `django.contrib.auth` :

```python
INSTALLED_APPS = [
    "django.contrib.auth",
    "django.contrib.sessions",
    ...
    "django-pyoidc"
]
```

Don't forget to add the session middleware ! Add in your `settings.py` :

```python
MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
]
```

Now is time to run a migrate operation, as we create a database table ([read why here](https://django-pyoidc.readthedocs.io/en/latest/explanation.html#cache-management)). Run in your project dir :

```
./manage.py migrate
```

We also need a cache ([read why here](https://django-pyoidc.readthedocs.io/en/latest/explanation.html#cache-management)), so let's configure a dumb one for development purposes. Add in your `settings.py` :

```python
CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        "LOCATION": "unique-snowflake",
    }
}
```

Now you can pick an identity provider from the [available providers](https://django-pyoidc.readthedocs.io/en/latest/user.html#providers). Providers class are a quick way to generate the library configuration and URLs for a givenv identity provider. You can also use [manual set] if you wish.

Create a file named `oidc.py` next to your settings file and initialize your provider there :

```python
from django_pyoidc.providers.keycloak import KeycloakProvider

my_oidc_provider = KeycloakProvider(
    op_name="keycloak",
    client_secret="s3cret",
    client_id="my_client_id",
    keycloak_base_uri="http://keycloak.local:8080/auth/", # we use the auth/ path prefix option on Keycloak
    keycloak_realm="Demo",
    logout_redirect="http://app.local:8082/",
    failure_redirect="http://app.local:8082/",
    success_redirect="http://app.local:8082/",
    redirect_requires_https=False,
)
```

You can then add to your django configuration the following line :

```python
from .oidc_providers import my_oidc_provider

DJANGO_PYOIDC = {
    **my_oidc_provider.get_config(allowed_hosts=["app.local:8082"]),
}
```

Finally, add OIDC views to your url configuration (`urls.py`):

```python
from .oidc_providers import my_oidc_provider

urlpatterns = [
    path("auth", include(my_oidc_provider.get_urlpatterns())),
]
```

And you are ready to go !

If you struggle with those instructions, take a look at [the quickstart tutorial](https://django-pyoidc.readthedocs.io/en/latest/tutorial.html#getting-started).

## Usage/Examples

We wrote an extensive collection of 'how-to' guides in the [documentation](https://django-pyoidc.readthedocs.io/en/latest/how-to.html).

## Appendix

- [Development instructions](./DEVELOPMENT.md)

## Commercial support

This project is sponsored by Makina Corpus. If you require assistance on your project(s), please contact us: contact@makina-corpus.com

## Report a security vulnerability

## License

[GPL](./LICENSE)


## Authors

- [@gbip](https://www.github.com/gbip)
- [@regilero](https://github.com/regilero)

