Skip to content

ampaulo/ms-identity-python-webapp-django

 
 

Repository files navigation

Sample: A Python Django web project to sign in users and call APIs with the Microsoft Entra ID

This is a Python web application that uses the Django framework and the Microsoft Entra ID to sign in users and make authenticated calls to the Microsoft Graph API.

Topology

Getting Started

Prerequisites

Installation

  1. This sample already implements sign-in and calling downstream API. You can clone its repo or download its zip package, and then start using it or build on top of it. (Alternatively, you can follow our tutorial to learn how to build this from scratch, or how to add auth to your existing project.)
  2. cd project_name
  3. Run pip install -r requirements.txt to install dependencies
  4. Run python manage.py migrate to initialize your Django project
  5. Copy .env.sample as .env, and then modify its content based on your application's registration.

Quickstart

  1. After finishing installation, now you can run python manage.py runserver localhost:5000 to start your development server. You may need to change to a different port to match your redirect_uri setup.
  2. Now visit http://localhost:5000

Tutorial

Note: You do not have to read this tutorial.

  • If you are starting a new project, you can begin with our sample and build on top of it.

The following chapters teach you how to build a Django project with Microsoft Entra ID from scratch. After that, you will also know how to modify an existing Python Django project to sign in users and call APIs with the Microsoft Entra ID.

Preface: Have a Django web project as a starting point

You can use Django's own tutorial, part 1 as a reference. What we need are these steps:

  1. django-admin startproject mysite

  2. python manage.py migrate

  3. python manage.py runserver localhost:5000 You may need to change to a different port to match your redirect_uri setup.

  4. Now, add an index view to your project. For now, it can simply return a "hello world" page to any visitor.

    from django.http import HttpResponse
    def index(request):
        return HttpResponse("Hello, world. Everyone can read this line.")

Chapter 1: Enable your Python Django web app to sign in users

  1. At the beginning of mysite/settings.py file, create a global Auth helper like this:

    from identity.django import Auth
    AUTH = Auth("your_client_id", client_credential=..., authority=..., redirect_uri=...)
  2. Inside the same mysite/settings.py file, add "identity", into the INSTALLED_APPS list, to enable the default templates came with the identity package.

    INSTALLED_APPS = [
     ...,
     "identity",
    ]
  3. Modify the mysite/urls.py to add these content:

    ...
    from django.conf import settings
    
    urlpatterns = [
        settings.AUTH.urlpattern,
        ...
    ]
  4. Now, inside the mysite/views.py, for each view that you would like to enforce user login, simply add a one-liner @settings.AUTH.login_required before each view. For example,

    ...
    from django.conf import settings
    
    @settings.AUTH.login_required
    def index(request):
        return HttpResponse("Hello, only signed-in user can read this.")

    That is it. Now visit http://localhost:5000 again, you will see the sign-in experience.

Chapter 2: Get an Access Token and call Microsoft Graph

This chapter begins where chapter 1 left off. We will add the following new view which will call a downstream API.

import json
from django.shortcuts import redirect, render
import requests

...

# here we demonstrate how to handle the error explicitly.
def call_downstream_api(request):
    token = settings.AUTH.get_token_for_user(["your_scope1", "your_scope2"])
    if "error" in token:
        return redirect(settings.AUTH.login)
    api_result = requests.get(  # Use access token to call downstream api
        "https://example.com/your/api",
        headers={'Authorization': 'Bearer ' + token['access_token']},
        timeout=30,
    ).json()  # Here we assume the response format is json
    return render(request, 'display.html', {
        "title": "Result of downstream API call",
        "content": json.dumps(api_result, indent=4),
    })

You can refer to our full sample here to pick up other minor details, such as how to modify urls.py accordingly, and how to add templates for this new view (and for the existing index() view).

What is next?

You may notice that, this sample's code base contains no templates used by sign-in. That is because the upstream helper library provides built-in minimalist templates. That is convenient, but at some point you may want to customize the look-and-feel. You can do so by copying the upstream templates into your own project's templates/identity sub-directory, and then start hacking.

Contributing

If you find a bug in the sample, please raise the issue on GitHub Issues.

If you'd like to contribute to this sample, see CONTRIBUTING.MD.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

About

This sample is functional. Please subscribe/watch this repo to receive release notification.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 88.0%
  • HTML 12.0%