如何在Python Flask应用中实现Azure AD SAML2.0 SSO配置?
Hey there! I’ve gone through the process of integrating Azure AD SAML2.0 SSO with a Flask app before, so I can share some solid libraries and step-by-step examples that should help you get up and running, including API setup and Python configuration details.
1. Flask-SAML2 (Flask-Native SAML Extension)
This library is built specifically for Flask, so it’s tightly integrated with the framework and requires minimal boilerplate. Perfect for straightforward SSO setups.
Installation
pip install flask-saml2
Project Structure
your_flask_app/ ├── app.py ├── saml_config.py └── templates/ └── index.html
SAML Configuration (saml_config.py)
Match these values to what you’ve already set up in the Azure AD portal:
from flask_saml2.config import Config as SAMLConfig class SAMLConfig(SAMLConfig): # Local Service Provider (SP) settings (must match Azure AD config) SAML_SP_ENTITY_ID = "https://your-ngrok-or-production-url/saml/metadata" SAML_SP_ASSERTION_CONSUMER_URL = "https://your-ngrok-or-production-url/saml/acs" SAML_SP_SINGLE_LOGOUT_URL = "https://your-ngrok-or-production-url/saml/slo" # Azure AD Identity Provider (IDP) settings (from Azure portal) SAML_IDP_ENTITY_ID = "https://sts.windows.net/your-tenant-id/" SAML_IDP_SSO_URL = "https://login.microsoftonline.com/your-tenant-id/saml2" SAML_IDP_SLO_URL = "https://login.microsoftonline.com/your-tenant-id/saml2" # Paste the certificate content downloaded from Azure AD here SAML_IDP_PUBLIC_CERT = """-----BEGIN CERTIFICATE----- YOUR_AZURE_AD_CERTIFICATE_CONTENTS_HERE -----END CERTIFICATE-----"""
Flask App Setup (app.py)
from flask import Flask, redirect, url_for, render_template from flask_saml2.sp import ServiceProvider from saml_config import SAMLConfig app = Flask(__name__) app.config.from_object(SAMLConfig) # Initialize SAML Service Provider sp = ServiceProvider() sp.init_app(app) # Protected homepage (requires SAML authentication) @app.route('/') def index(): if not sp.is_authenticated(): return redirect(url_for('sp.login')) # Fetch authenticated user details user = sp.get_current_user() return render_template('index.html', user=user) # Logout route @app.route('/logout') def logout(): return sp.logout() if __name__ == '__main__': # Use HTTPS (required for Azure AD; adhoc is for dev only) app.run(debug=True, ssl_context='adhoc', port=5000)
Example Template (templates/index.html)
<!DOCTYPE html> <html> <head> <title>Flask SAML SSO Demo</title> </head> <body> <h1>Welcome, {{ user.name }}!</h1> <p>Your Email: {{ user.email }}</p> <p>SAML Attributes: {{ user.attributes }}</p> <a href="{{ url_for('logout') }}">Sign Out</a> </body> </html>
Key Notes for Flask-SAML2
- Azure AD requires HTTPS for ACS URLs. For local development, use
ngrokto create a temporary HTTPS tunnel:ngrok http 5000, then update your Azure AD config with the ngrok URL. - Double-check that your SP entity ID and ACS URL in
saml_config.pyexactly match what you’ve configured in Azure AD.
2. python3-saml (Flexible, General-Purpose SAML Library)
If you need more control over the SAML flow or want to support advanced features, this library is a great choice. It’s framework-agnostic but works seamlessly with Flask.
Installation
pip install python3-saml
SAML Settings (settings.json)
Create this file in your project root with values aligned to your Azure AD setup:
{ "sp": { "entityId": "https://your-ngrok-or-production-url/saml/metadata", "assertionConsumerService": { "url": "https://your-ngrok-or-production-url/saml/acs", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, "singleLogoutService": { "url": "https://your-ngrok-or-production-url/saml/slo", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "x509cert": "", "privateKey": "" }, "idp": { "entityId": "https://sts.windows.net/your-tenant-id/", "singleSignOnService": { "url": "https://login.microsoftonline.com/your-tenant-id/saml2", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "singleLogoutService": { "url": "https://login.microsoftonline.com/your-tenant-id/saml2", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "x509cert": "YOUR_AZURE_AD_CERTIFICATE_CONTENTS_HERE" } }
Flask App Setup (app.py)
from flask import Flask, request, redirect, url_for, session, render_template from onelogin.saml2.auth import OneLogin_Saml2_Auth import json app = Flask(__name__) app.secret_key = "your-secure-secret-key-here" # Use a strong key in production def init_saml_auth(req): with open('settings.json', 'r') as f: settings = json.load(f) return OneLogin_Saml2_Auth(req, settings) def prepare_flask_request(request): # Convert Flask request format to python3-saml's expected format return { 'http_host': request.host, 'script_name': request.path, 'server_port': request.server_port, 'get_data': request.args.copy(), 'post_data': request.form.copy() } # Initiate SAML login flow @app.route('/saml/login') def saml_login(): req = prepare_flask_request(request) auth = init_saml_auth(req) return redirect(auth.login()) # Process SAML assertion response @app.route('/saml/acs', methods=['POST']) def saml_acs(): req = prepare_flask_request(request) auth = init_saml_auth(req) auth.process_response() errors = auth.get_errors() if errors: return f"Authentication failed: {', '.join(errors)}", 401 # Store user data in session session['saml_user'] = { 'name': auth.get_nameid(), 'email': auth.get_attribute('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress')[0], 'attributes': auth.get_attributes() } return redirect(url_for('index')) # Initiate SAML logout flow @app.route('/saml/slo') def saml_slo(): req = prepare_flask_request(request) auth = init_saml_auth(req) name_id = session.get('saml_user', {}).get('name') session.clear() return redirect(auth.logout(name_id=name_id)) # Protected homepage @app.route('/') def index(): if 'saml_user' not in session: return redirect(url_for('saml_login')) return render_template('index.html', user=session['saml_user']) if __name__ == '__main__': app.run(debug=True, ssl_context='adhoc', port=5000)
Key Notes for python3-saml
- This library gives you full control over SAML request/response processing, making it ideal for custom workflows.
- Ensure your Flask session is securely configured (use a strong secret key, consider server-side sessions in production).
- HTTPS Requirement: Azure AD will not send SAML assertions to HTTP endpoints. Always use HTTPS in production, and use
ngrokfor local testing. - Metadata Validation: Double-check that your Azure AD IDP metadata and local SP configuration are in sync (entity IDs, URLs, certificates).
内容的提问来源于stack exchange,提问作者Vivek Rajyaguru

