Part 1 - Make a Provider in a Minute
Scenario
You want to make your own Authorization Server to issue access tokens to client applications for a certain API.
Start Your App
During this tutorial you will make an XHR POST from a Heroku deployed app to your localhost instance. Since the domain that will originate the request (the app on Heroku) is different from the destination domain (your local instance), you will need to install the django-cors-headers app. These “cross-domain” requests are by default forbidden by web browsers unless you use CORS.
Create a virtualenv and install django-oauth-toolkit and django-cors-headers:
pip install django-oauth-toolkit django-cors-headers
Start a Django project, add oauth2_provider and corsheaders to the installed apps, and enable admin:
INSTALLED_APPS = {
'django.contrib.admin',
# ...
'oauth2_provider',
'corsheaders',
}
Include the Django OAuth Toolkit urls in your urls.py, choosing the urlspace you prefer. For example:
from django.urls import path, include
urlpatterns = [
path("admin", admin.site.urls),
path("o/", include('oauth2_provider.urls', namespace='oauth2_provider')),
# ...
]
Include the CORS middleware in your settings.py:
CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django’s CommonMiddleware or Whitenoise’s WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.
MIDDLEWARE = (
# ...
'corsheaders.middleware.CorsMiddleware',
# ...
)
Allow CORS requests from all domains (just for the scope of this tutorial):
CORS_ORIGIN_ALLOW_ALL = True
Include the required hidden input in your login template, registration/login.html.
The {{ next }}
template context variable will be populated with the correct
redirect value. See the Django documentation
for details on using login templates.
<input type="hidden" name="next" value="{{ next }}" />
As a final step, execute the migrate command, start the internal server, and login with your credentials.
Create an OAuth2 Client Application
Before your Application can use the Authorization Server for user login, you must first register the app (also known as the Client.) Once registered, your app will be granted access to the API, subject to approval by its users.
Let’s register your application.
You need to be logged in before registration. So, go to http://localhost:8000/admin and log in. After that point your browser to http://localhost:8000/o/applications/ and add an Application instance. Client id and Client Secret are automatically generated; you have to provide the rest of the informations:
User: the owner of the Application (e.g. a developer, or the currently logged in user.)
Redirect uris: Applications must register at least one redirection endpoint before using the authorization endpoint. The Authorization Server will deliver the access token to the client only if the client specifies one of the verified redirection uris. For this tutorial, paste verbatim the value https://www.getpostman.com/oauth2/callback
Allowed origins: Browser-based clients use Cross-Origin Resource Sharing (CORS) to request resources from origins other than their own. Provide space-separated list of allowed origins for the token endpoint. The origin must be in the form of “://” [ “:” ], such as https://login.mydomain.com or http://localhost:3000. Query strings and hash information are not taken into account when validating these URLs. This does not include the ‘Redirect URIs’ or ‘Post Logout Redirect URIs’, if those domains will also use the token endpoint, they must be included in this list.
Client type: this value affects the security level at which some communications between the client application and the authorization server are performed. For this tutorial choose Confidential.
Authorization grant type: choose Authorization code
Name: this is the name of the client application on the server, and will be displayed on the authorization request page, where users can allow/deny access to their data.
Hash client secret: checking this hashes the client secret on save so it cannot be retrieved later. This should be unchecked if you plan to use OIDC with
HS256
and want to check the tokens’ signatures using JWT. Otherwise, Django OAuth Toolkit cannot use Client Secret to sign the tokens (as it cannot be retrieved later) and the hashed value will be used when signing. This may lead to incompatibilities with some OIDC Relying Party libraries.
Take note of the Client id and the Client Secret then logout (this is needed only for testing the authorization process we’ll explain shortly)