Metadata-Version: 2.1
Name: django-jwt-oidc
Version: 0.2.2
Summary: Django library that implements the authentification for OpenId SSO with JWT from oauth2.
Home-page: https://github.com/Casassarnau/django-jwt
Author: Arnau Casas Saez
Author-email: casassarnau@gmail.com
License: MIT
Project-URL: Bug Tracker, https://github.com/Casassarnau/django-jwt/issues
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE.md

# Django jwt
Django library that implements the authentification for OpenId SSO with JWT from oauth2.
This authentification is compatible with django session workflow and the RestFramework library.

## Installation

Install the library with pip
```bash
pip install django-jwt-oidc
```

Add the `django_jwt` package into your `INSTALLED_APPS` in your settings.py file
```python
INSTALLED_APPS = [
    ...
    'django_jwt',
    ...
]
```

## Django [WIP]
This is what you need to do in order that your Django application will authenticate with JWT.

## RestFramework
This settings are for views inherits RestFramework library from Django.
**You will need to install RestFramework on your own to your app first**

### View setting
You can add this to your APIviews class by adding `JWTTokenAuthentication` to `authentification_classes` attribute.
In this example, the view requires that all requests must have JWT Bearer Authentication.

```python
from rest_framework import permissions, views
from django_jwt import JWTTokenAuthentication


class ExampleAPIView(view.APIView):
    authentication_classes = [JWTTokenAuthentication]
    permission_classes = [permissions.IsAuthenticated]
```
### Global setting
If all your application can work with JWT Bearer Authentication you can add the `JWTTokenAuthentication` class to `DEFAULT_AUTHENTICATION_CLASSES` setting on settings.py of your app.

```python
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'django_jwt.rest_framework.JWTTokenAuthentication',
    ]
}
```
## Fake server (deployment only)
This is an extra functionality of the `django_jwt` app that makes a OpenId server with oauth 2.0 with implicit flow with an input to "log in" as whatever sub value you want. 

### Installation

- Install [django-cors-headers](https://pypi.org/project/django-cors-headers/) library into your app. Required in order to control the CORS policy from your frontend.
- Add your frontend domain into `CORS_ALLOWED_ORIGINS`.
- Change the [CLIENT_JWT \[ OPENID2_URL \]](#openid2_url--jwt_client-) setting to `'fake'`.
- Set up the [CLIENT_JWT \[ CLIENT_ID \]](#client_id--jwt_client-) setting to the same client id your frontend is targeting.
- Include the `django_jwt.urls` into your `urls.py`.
- Set up the `DEFAULT_DOMAIN` setting on your Django settings. Example:
```python
DEFAULT_DOMAIN = 'https://localhost:8000'
```
- Set up your frontend url into the path that you included in `urls.py`.

## Server
This is an extra app of the django_jwt app that deploys a OpenId server with oauth 2.0 with implicit flow (more coming soon).
The JWTs are signed by a RS256 algorithm that regenerates the rsa private keys.
Access tokens expire after 1 hour kept by the Implicit Flow protocol. <br>
**Django JWT Server does not provide for a login view.**

### Installation
- Install [django-cors-headers](https://pypi.org/project/django-cors-headers/) library into your app. Required in order to control the CORS policy from your apps. **There is no need to add the domains one by one**
- Add `django_jwt.server` to your installed apps.
- Change the [CLIENT_JWT \[ OPENID2_URL \]](#openid2_url--jwt_client-) setting to `'local'`.
- Migrate the database with `python manage.py migrate`.
- Add your implemented Django log in into `LOGIN_URL` setting on `settings.py`.
- Run your app in order to set up your hosts into the WebPage model.
- (Optional) If you want to use your id_tokens in your app, set up the [CLIENT_JWT \[ CLIENT_ID \]](#client_id--jwt_client-) setting to the same client id that you just created.

## Settings
The settings are separated into 2 main Django settings `JWT_CLIENT` for the `django_jwt` app and `JWT_SERVER` for the `django_jwt.server` app.

### OPENID2_URL [ JWT_CLIENT ]
There is 3 types of configurations for this field:

- **URL:** The openid service url without the `/.well-known/openid-configuration` path.
- **Fake server:** In case of **development** and using jwt from the fake server you need to set this to `'fake'`.
- **OpenId server:** If you want to deploy the openId app, you need to set to `'local'` in order to validate jwt tokens. Only for RestFramework.

### CLIENT_ID [ JWT_CLIENT ]
This is the client id of the openId service you are using. <br>
If you want to validate the jwt from the OpenId server by `django_jwt.server` app you will need to add here the generated client_id on the admin page.

### RENAME_ATTRIBUTES [ JWT_CLIENT ]
Dictionary to redirect the data and the `sub` attribute into the User attributes.

### CREATE_USER [ JWT_CLIENT ]
Boolean that creates a Django user by default if the user doesn't exists if set to `False`.

### DEFAULT_ATTRIBUTES [ JWT_CLIENT ]
Dictionary that sets default values to new Users created.
This example sets the all the attibutes of users created by the library `auto_created` to `True`.

### COOKIE_NAME [ JWT_CLIENT ]
String that represents the identification of the cookie id of the JWT.

### Example of JWT_CLIENT on settings.py

```python
JWT_CLIENT = {
    'OPENID2_URL': 'https://localhost:8000',    # Required
    'CLIENT_ID': 'client_id',                   # Required
    'RENAME_ATTRIBUTES': {'sub': 'username'},   # Optional
    'DEFAULT_ATTRIBUTES': {},                   # Optional
    'CREATE_USER': True,                        # optional
    'COOKIE_NAME': 'id_token'                   # Optional
}
```

### JWT_EXPIRATION_TIME [ JWT_SERVER ]
This setting is to change the expiration time (in seconds) for JWT generated by the server. This not includes the fake server.

### JWK_EXPIRATION_TIME [ JWT_SERVER ]
This setting is to change the expiration time (in seconds) for the JWK generated by the server. This must be grater than `JWT_EXPIRATION_TIME` 

### Example of JWT_SERVER on settings.py

```python
JWT_SERVER = {
    'JWK_EXPIRATION_TIME': 3600,                # Optional
    'JWT_EXPIRATION_TIME': 14400                # Optional
}
```

### Changing the values of the jwt
You can also modify attributes like adding something to the value creating a change_[attribute_name] method on the User model.<br>
Example of changing the username attribute:

```python
class User(AbstractBaseUser):
    def change_username(self, value):
        return value + '@jwt'
```

### Changing the default creation of the user
You can also change the creation method of the BaseUserManager of the AbstractBaseUser model in order to customize its default creation.

```python
class UserManager(BaseUserManager):
    def get_or_create(self, defaults=None, **kwargs):
        ...

class User(AbstractBaseUser):
    objects = UserManager()
    ...
```


