|
| 1 | +# Using the OIDC Authentication Backend to request a resource server |
| 2 | + |
| 3 | +Once your project is configured with the OIDC authentication backend, you can use it to request resources from a resource server. This guide will help you set up and use the `ResourceServerBackend` for token introspection and secure API access. |
| 4 | + |
| 5 | +## Configuration |
| 6 | + |
| 7 | +You need to follow the steps from [how-to-use-oidc-backend.md](how-to-use-oidc-backend.md) |
| 8 | + |
| 9 | +## Additional Settings for Resource Server Communication |
| 10 | + |
| 11 | +To enable your application to communicate with protected resource servers, you'll need to configure token storage in your Django settings: |
| 12 | + |
| 13 | +```python |
| 14 | +# Store OIDC tokens in the session |
| 15 | +OIDC_STORE_ACCESS_TOKEN = True # Store the access token in the session |
| 16 | +OIDC_STORE_REFRESH_TOKEN = True # Store the encrypted refresh token in the session |
| 17 | + |
| 18 | +# Required for refresh token encryption |
| 19 | +OIDC_STORE_REFRESH_TOKEN_KEY = "your-32-byte-encryption-key==" # Must be a valid Fernet key (32 url-safe base64-encoded bytes) |
| 20 | +``` |
| 21 | + |
| 22 | +### Purpose of Each Setting |
| 23 | + |
| 24 | +1. **`OIDC_STORE_ACCESS_TOKEN`**: When set to `True`, the access token received from the OIDC provider will be stored in the user's session. This token is required for making authenticated requests to protected resource servers. |
| 25 | + |
| 26 | +2. **`OIDC_STORE_REFRESH_TOKEN`**: When set to `True`, enables storing the refresh token in the user's session. The refresh token allows your application to request a new access token when the current one expires without requiring user re-authentication. |
| 27 | + |
| 28 | +3. **`OIDC_STORE_REFRESH_TOKEN_KEY`**: This is a cryptographic key used to encrypt the refresh token before storing it in the session. This provides an additional layer of security since refresh tokens are sensitive credentials that can be used to obtain new access tokens. |
| 29 | + |
| 30 | +## Generating a Secure Refresh Token Key |
| 31 | + |
| 32 | +You can generate a secure Fernet key using Python: |
| 33 | + |
| 34 | +```python |
| 35 | +from cryptography.fernet import Fernet |
| 36 | +key = Fernet.generate_key() |
| 37 | +print(key.decode()) # Add this value to your settings |
| 38 | +``` |
| 39 | + |
| 40 | +## Using the Stored Tokens |
| 41 | + |
| 42 | +Once you have configured these settings, your application can use the stored tokens to make authenticated requests to resource servers: |
| 43 | + |
| 44 | +```python |
| 45 | +import requests |
| 46 | +from django.http import JsonResponse |
| 47 | + |
| 48 | +def call_resource_server(request): |
| 49 | + # Get the access token from the session |
| 50 | + access_token = request.session.get('oidc_access_token') |
| 51 | + |
| 52 | + if not access_token: |
| 53 | + return JsonResponse({'error': 'Not authenticated'}, status=401) |
| 54 | + |
| 55 | + # Make an authenticated request to the resource server |
| 56 | + response = requests.get( |
| 57 | + 'https://resource-server.example.com/api/resource', |
| 58 | + headers={'Authorization': f'Bearer {access_token}'}, |
| 59 | + ) |
| 60 | + |
| 61 | + return JsonResponse(response.json()) |
| 62 | +``` |
| 63 | + |
| 64 | +## Token Refresh management |
| 65 | + |
| 66 | +### View Based Token Refresh (via decorator) |
| 67 | + |
| 68 | +Request the access token refresh only on specific views using the `refresh_oidc_access_token` decorator: |
| 69 | + |
| 70 | +```python |
| 71 | +from lasuite.oidc.decorators import refresh_oidc_access_token |
| 72 | + |
| 73 | +class SomeViewSet(GenericViewSet): |
| 74 | + |
| 75 | + @method_decorator(refresh_oidc_access_token) |
| 76 | + def some_action(self, request): |
| 77 | + # Your action logic here |
| 78 | + |
| 79 | + # The call to the resource server |
| 80 | + access_token = request.session.get('oidc_access_token') |
| 81 | + requests.get( |
| 82 | + 'https://resource-server.example.com/api/resource', |
| 83 | + headers={'Authorization': f'Bearer {access_token}'}, |
| 84 | + ) |
| 85 | +``` |
| 86 | + |
| 87 | +This will trigger the token refresh process only when the `some_action` method is called. |
| 88 | +If the access token is expired, it will attempt to refresh it using the stored refresh token. |
| 89 | + |
| 90 | +### Automatic Token Refresh (via middleware) |
| 91 | + |
| 92 | +You can also use the `RefreshOIDCAccessToken` middleware to automatically refresh expired tokens: |
| 93 | + |
| 94 | +```python |
| 95 | +# Add to your MIDDLEWARE setting |
| 96 | +MIDDLEWARE = [ |
| 97 | + # Other middleware... |
| 98 | + 'lasuite.oidc.middleware.RefreshOIDCAccessToken', |
| 99 | +] |
| 100 | +``` |
| 101 | + |
| 102 | +This middleware will: |
| 103 | +1. Check if the current access token is expired |
| 104 | +2. Use the stored refresh token to obtain a new access token |
| 105 | +3. Update the session with the new token |
| 106 | +4. Continue processing the request with the fresh token |
| 107 | + |
| 108 | +If token refresh fails, the middleware will return a 401 response with a `refresh_url` header to redirect the user to re-authenticate. |
| 109 | + |
0 commit comments