Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

███████╗███████╗ ██████╗     ██╗    ██████╗
██╔════╝██╔════╝██╔═══██╗   ██╔╝   ██╔══██╗
███████╗███████╗██║   ██║  ██╔╝    ██║  ██║
╚════██║╚════██║██║   ██║ ██╔╝     ██║  ██║
███████║███████║╚██████╔╝██╔╝      ██████╔╝
╚══════╝╚══════╝ ╚═════╝ ╚═╝       ╚═════╝

  Microsoft Entra ID — OAuth 2.0 SSO Integration

Python Flask Microsoft Entra ID MSAL License

Enterprise-grade Single Sign-On using Microsoft Entra ID, OAuth 2.0 Authorization Code Flow, and Microsoft Graph API

OverviewArchitectureSetupScreenshotsConcepts


📌 Overview

This project implements a production-pattern OAuth 2.0 / OpenID Connect (OIDC) Single Sign-On flow using Microsoft Entra ID (formerly Azure Active Directory) as the Identity Provider.

A Python Flask web application authenticates users through Entra ID, exchanges authorization codes for access tokens using MSAL (Microsoft Authentication Library), and retrieves live user profile data from the Microsoft Graph API — the same architecture used by enterprise SaaS applications like Microsoft 365, Teams, and SharePoint.

Key Highlights

  • 🔐 OAuth 2.0 Authorization Code Flow — industry-standard, secure server-side auth
  • 🛡️ CSRF Protection — state parameter validation on every callback
  • 👤 Microsoft Graph API — live user profile retrieval post-authentication
  • 🏢 Single Tenant — scoped to one Entra ID directory (enterprise pattern)
  • 🔑 MSAL Integration — Microsoft's official auth library for Python

🏗️ Architecture

┌─────────────┐         ┌──────────────────┐         ┌─────────────────────┐
│             │ 1.Login │                  │ 2.Auth  │                     │
│    User     │────────▶│   Flask App      │────────▶│  Microsoft Entra ID │
│  (Browser)  │         │  (localhost:5000)│         │  (login.microsoft   │
│             │         │                  │◀────────│   online.com)       │
└─────────────┘         │                  │ 3.Code  └─────────────────────┘
                        │                  │
                        │                  │ 4.Exchange code → Token
                        │                  │────────────────────────▶ Entra ID
                        │                  │◀──────────────────────── Access Token
                        │                  │
                        │                  │ 5. GET /me (with token)
                        │                  │────────────────────────▶ ┌─────────────┐
                        │                  │◀──────────────────────── │  Microsoft  │
                        │                  │  User Profile JSON        │  Graph API  │
                        └──────────────────┘                          └─────────────┘

Tech Stack

Layer Technology
Identity Provider Microsoft Entra ID
Auth Protocol OAuth 2.0 + OpenID Connect (OIDC)
Auth Library MSAL for Python v1.36
Backend Python 3.9+ / Flask 3.1
User Data Microsoft Graph API v1.0
Config python-dotenv

⚡ Quick Start

Prerequisites

1. Clone the repository

git clone https://github.com/YOUR_USERNAME/entra-sso-oauth2.git
cd entra-sso-oauth2

2. Register your app in Entra ID

  1. Go to entra.microsoft.comApp registrationsNew registration
  2. Name: My SSO App | Account type: Single tenant | Redirect URI: http://localhost:5000/callback
  3. Copy your Application (client) ID and Directory (tenant) ID from Overview
  4. Go to Certificates & secretsNew client secret → copy the value
  5. Go to API permissions → Add: openid, profile, email, User.ReadGrant admin consent

3. Configure environment

cp .env.example .env

Edit .env with your values:

CLIENT_ID=your-application-client-id
CLIENT_SECRET=your-client-secret-value
TENANT_ID=your-directory-tenant-id
REDIRECT_URI=http://localhost:5000/callback
FLASK_SECRET_KEY=your-random-secret-key

4. Install dependencies & run

python -m venv venv
venv\Scripts\activate        # Windows
# source venv/bin/activate   # macOS/Linux

pip install -r requirements.txt
python app.py

5. Open in browser

http://localhost:5000

Click Sign in with Microsoft → authenticate → see your profile. ✅


📸 Screenshots

Step 1 — App Registration in Entra ID Portal

App Registration

Step 2 — API Permissions Configured

API Permissions

Step 3 — Environment Configuration

ENV File

Step 4 — Python Virtual Environment Setup

Python Setup

Step 5 — Flask App Code in VS Code

VS Code

Step 6 — Flask Server Running

Flask Running

Step 7 — SSO Working — Authenticated User Profile

SSO Working


🧠 What I Learned

OAuth 2.0 Authorization Code Flow

The most secure OAuth flow for server-side apps. Unlike the deprecated Implicit Flow, the authorization code is exchanged server-side — the access token never touches the browser.

ID Token vs Access Token

  • ID Token (JWT) — proves who the user is (authentication)
  • Access Token — grants permission to call APIs like Graph (authorization)

CSRF Protection via State Parameter

Every auth request generates a random state UUID stored in the session. The callback validates it matches — preventing cross-site request forgery attacks.

Scopes & Least Privilege

Only User.Read is requested — following the principle of least privilege. The app gets exactly what it needs, nothing more.

Microsoft Graph API

A unified REST API endpoint (https://graph.microsoft.com/v1.0/me) that returns the authenticated user's directory profile using the access token as a Bearer credential.


📁 Project Structure

entra-sso-oauth2/
├── app.py                 # Main Flask application
├── requirements.txt       # Python dependencies
├── .env.example           # Environment variable template
├── .gitignore             # Git ignore rules
├── README.md              # This file
└── screenshots/           # Step-by-step project screenshots
    ├── 01_app_registration.png
    ├── 02_api_permissions.png
    ├── 03_env_file.png
    ├── 04_python_setup.png
    ├── 06_vscode_app.png
    ├── 07_flask_running.png
    └── 08_sso_working.png

🔒 Security Notes

  • Never commit .env — it's in .gitignore for a reason
  • Regenerate your CLIENT_SECRET if it's ever exposed
  • Use a strong random FLASK_SECRET_KEY in production
  • In production, serve over HTTPS only and use a WSGI server (Gunicorn, uWSGI)

🗺️ IAM Learning Roadmap

This is Project 3 of 5 in my Microsoft Entra ID IAM learning path:

# Project Level Status
1 User & Group Management Automation Beginner
2 Conditional Access Policy Lab Beginner–Intermediate
3 App Registration & OAuth 2.0 SSO Intermediate ✅ Complete
4 Privileged Identity Management Dashboard Advanced 🔄 In Progress
5 Zero Trust Identity Governance Pipeline Expert ⏳ Upcoming

📄 License

MIT License — see LICENSE for details.


Built by Muhammad Ahmad | Microsoft Entra ID IAM Portfolio Project

About

OAuth 2.0 SSO with Microsoft Entra ID using Python Flask & MSAL. Implements Authorization Code Flow, CSRF protection, and Microsoft Graph API integration for live user profile retrieval.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages